Trameによる3次元Web可視化
By K.Yoshimi
近年、3次元可視化は、スマートフォン、タブレット、デスクトップ、スパコンなど多様なハードウェア上で行えることが期待されています。
しかし、それを行うの容易ではありません。
trameは、 このような広範なアプリケーションで動作する可視化アプリケーションを開発するための、統合フレームワークを提供します。 (Trameとはフランス語で「物事を結びつける核」という意味です。)
trameのフレームワークを使用すると、PythonでWebブラウザベースの3次元可視化アプリケーションを書くことができます。 もっと言うと、Pythonに慣れていれば、JavaScriptやWeb開発のさまざまなフレームワークを知らなくても、3次元可視化のWeb開発ができるようになります。
また、Pythonに存在する豊富なライブラリ群(データサイエンス、科学計算、人工知能、医療画像などの分野)と併用して、 高度なデータ分析ができるのも利点となるでしょう。
この記事では、
https://kitware.github.io/trame/docs/
を基に、trameの導入部分を紹介します。
セットアップ
それでは、セットアップを始めます。
trameは、Python3.6以上であれば動作します。ただし、ParaViewとの連携を考えている場合は、Python 3.9を使用する必要がありますので、ご注意ください。
最初に、Pythonの仮想環境を設定します。
※ ご自身のPythonの環境によって、仮想環境の設定方法は異なりますので、環境に合わせた方法で作成ください。下記は、一例です。
python3.9 -m venv .venv
source ./.venv/bin/activate
trameをインストールします。インストールは下記のコマンドです。
python -m pip install --upgrade pip
pip install "trame"
pip install "vtk>=9.1.0"
VTKオブジェクトを描画する例題
ここで紹介する例は、vtkライブラリと同様な記述で、円錐をローカルに描画するものです。
使用するスクリプトは下記です。 https://github.com/Kitware/trame/blob/master/examples/VTK/SimpleCone/LocalRendering.py
それでは、早速、このスクリプトを下記コマンドで実行してみましょう。
python LocalRendering.py --port 1234
すると、下図のように、円錐が描画されたブラウザが自動で立ち上がります。
Web開発で必要な設定をほとんどしなくても、Webアプリケーションが作成されてしまいました。
上右図では、スクロールバーを移動すると、円錐の解像度を変更することもできます。
画面操作は以下の通りです。
画面操作
- 回転:左クリックしたまま、マウスを移動します。
- 拡大・縮小:右クリックしたまま、マウスを上下に移動します。
- 平行移動:中クリックしたまま、マウスを移動します。
以下では、LocalRendering.pyの中身を見ていきます。
VTKのインポート
それでは、スクリプトの中身を見ていきましょう。
最初に、vtkとvuetifyをtrame.htmlからインポートしています。
from trame.html import vuetify, vtk
これにより、trameのヘルパー関数で、vtkとvuetifyにアクセスできるようになります。
次に、描画したいvtkのオブジェクトをインポートする必要があります。
この例では単純な円錐を描画するので、vtkConeSourceをインポートします。
from vtkmodules.vtkFiltersSources import vtkConeSource
その他のVTKオブジェクトを使用する場合は、同様にしてインポートしていくことになります。
インタラクターとレンダリングに関わるVTKのモジュールをインポートします。
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor,
)
vtkInteractorStyleSwitchは、インタラクタの初期化に使用されます。
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa
注: #noqa は、問題のある行のチェックを無視するようリンターに指示します。
VTKのパイプライン
それでは、PythonでVTKパイプラインを記述して、アプリケーションに可視化機能を追加していきます。
※ VTKライブラリに不慣れな場合は下記の資料を参照ください:
以降、断片的に説明をしていきます。
まず、vtkRendererとvtkRenderWindowを作成します。続けて、レンダラーをrenderWindowに追加することで両者を結びつけます。
renderer = vtkRenderer()
renderWindow = vtkRenderWindow()
renderWindow.AddRenderer(renderer)
次に、マウス/キー/タイムイベントのためのインタラクション機構を提供するvtkRenderWindowInteractorを定義します。
具体的には、インタラクターを作成し、renderWindowに接続し、インタラクションのスタイルを設定します。
renderWindowInteractor = vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
次に、目的の描画を作成します。このためには、オブジェクト、マッパー、アクターを作成しておきます。
cone_source = vtkConeSource()
mapper = vtkPolyDataMapper()
actor = vtkActor()
mapper.SetInputConnection(cone_source.GetOutputPort())
actor.SetMapper(mapper)
vtkConeSourceは、円錐ポリゴンを生成します。
次に、vtkPolyDataMapperを作成して、円錐ポリゴンをグラフィカルな表現にマッピングします。
これには、マッパーのinput connectionに作成した円錐ポリゴンを設定することで、円錐をマッパーに接続します。
次に、アクターを作成し、マッパーをアクターに接続します。
最後に、すべてのアクターをレンダラーに追加し、カメラをリセットして、レンダリングします。
renderer.AddActor(actor)
renderer.ResetCamera()
以上のように、trameで作成するVTKのパイプラインは、 通常のPython VTKで作成する場合と全く同じ記述になります。
ローカルレンダリングとリモートレンダリング
trameは、ローカルレンダリングとリモートレンダリングの両方に対応しています。
この例では、ローカルにレンダリングを行うように設定しています。
html_view = vtk.VtkLocalView(renderWindow, ref="view")
もし、リモートレンダリングにする場合は、下記のように設定します。
html_view = vtk.VtkRemoteView(renderWindow)
最後に、レンダラーを格納するコンテナを定義します。
with layout.content:
vuetify.VContainer(
fluid=True,
classes="pa-0 fill-height",
children=[html_view],
)
なお、ローカルとリモートでのレンダリング方法は、それぞれ、次のような利点と欠点がありますので、実際に、Webアプリケーションを開発する場合は、 ローカルにするか、リモートにするかを慎重に検討する必要があります。
ローカルレンダリング
利点:
- サーバーにGPUは必要ありません。GPUを搭載したシステムは、購入してもクラウドでレンタルしても、高価になります。ローカルレンダリングにすると、これらのコストを、エンドユーザーに押し付けることができます。
- レンダリングのフレーム/秒を高くすることができます。ブラウザのローカルGPUへのアクセスする技術は日々進歩してますので、デスクトップアプリケーションとほぼ同等のパフォーマンスを得ることができます。
欠点:
- レンダリングするデータを、サーバーからクライアントに転送する必要があります。この転送が遅すぎたり、大きすぎたりするとレンダリングに支障をきたします。
- データはどこでグラフィックに加工する予定でしょうか?この処理により、サーバー側またはクライアント側の負荷や遅延が増加する可能性があります。
リモートレンダリング
利点:
- 描画するデータを転送しません。描画する画像だけが転送されます。
- レンダリングは並列分散処理を活用することで、大規模データを扱うことができます。
- より多様なクライアントに対応することができます。画像の受信とレンダリングさえできれば、スマートフォンからワークステーションまで、どこでも対応可能です。。
欠点:
- フレーム/秒のレンダリングは、画像配信の速度とレイテンシーによって上限が決まってしまいます。
- 高性能なサーバーを用意する必要があります。リモートソフトウェアレンダリングは可能ですが、フレームレートはさらに影響を受けます。
UpdateとStart
クライアントとサーバーの準備ができましたら、html_view.update()を呼び出してビュー(html_view)を更新する必要があります。
これを行うには、レイアウトを修正して、on_ready変数に、サーバーとクライアントの準備ができたときに呼び出される関数を渡します。
layout = SinglePage("VTK Remote View - Local Rendering", on_ready=update_cone)
以上は、簡単なtrameの使用法の説明でした。
おわりに
この記事では、trameを使用して、3次元可視化を行うWebアプリケーションを、Pythonで作成できることを紹介しました。
Vuetifyの機能を使用して、もっと洗練されたアプリケーションを作成することも可能です。
これからは、CAE/CFDの分野も、クラウド上で実行されるようになっていくと思いますので、 ぜひとも、この技術を習得して、3次元可視化をWebブラウザ上に実装できるようになりたいものですね。