Metal 公式サンプル

アップルが公開している Metal の公式サンプルで気になったプロジェクトなど。

CAMetalLayer 関係

CA というのがわからなかったが、Core Animation のことらしい。
興味深くはあるが、私はあまり使わないかな。

Ray Tracing と InterSection を組み合わせたプロジェクト

綺麗だ。。。

が、ここら辺までくると文字ベースの解説は一切なし。
動画はあるけど。

2D texture 関係

特にサンプルは挙げられていないが、取り扱うデータによって何を採用したらいいのか?みたいなことがこの記事に書いてある。

具体的なサンプルとしては、とりあえず

https://developer.apple.com/documentation/metal/onscreen_presentation/reading_pixel_data_from_a_drawable_texture?language=objc

https://developer.apple.com/documentation/metal/textures/creating_and_sampling_textures?language=objc

の二つをチェック。

前者は、ビルドするとこんなウィンドウが表示される。

ドラッグすると、ドラッグした領域をデスクトップ上にファイルの形で切り出してくれる。
MTKView 上でマウスの位置に応じてちょっと工夫した処理を行いたい、なんてときに使えるかもしれない。

後者は、これ。

 

かなり以前からある基本的なプロジェクトでした。

が、今から思うとこれはこれで使い道ありそう。

(続く)

 

Metal がよくわからんという人は公式サンプルから入るといいと思う

以前に「Metal 入門」という記事を書いたことがあるのだが、Metal 関係の情報は乏しいせいかネット上ではかなり参照されているようだ。

放置するのもなんなので、先日、Metal を仕様する際に出てくる「コマンド」に関して追記した。

そこで提示したサンプルは Objective-C にするのか Swift にするのか迷ったのだが、結局、Swift にした。

じゃあ、Objective-C ではどうやるのってのが本記事。

Objective-C で書かれたサンプルは本当に少ないが、Objective-C から Metal を使いたい人は公式にあるサンプルあたりから入るといいと思う。

お馴染みの三角形を描くサンプルもある。

ただし、同一プロジェクトに iOS と tvOS のターゲットも同包されているので、MacOS だけ取り出しておいた方がわかりやすい。

こんな感じになる。

以下、このサンプルに関して注意点などメモ。

MTKView の設定

View は MTKView にする必要があるが、Xcode の操作性がイマイチで、手動で MTKView に設定する必要がある。

ViewPort

ところで、今回のサンプルでは、ウィンドウのサイズを変えても描画される三角形の大きさは変わらない。

これは ViewPort を使うことで以下のように実現している。

内部的には、ウィンドウに何らかの変化が起こると delegate の以下のメソッドが呼び出されている。

/// Called whenever view changes orientation or is resized
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
{
    // Save the size of the drawable to pass to the vertex shader.
    _viewportSize.x = size.width;
    _viewportSize.y = size.height;
}

要するに実際のウインドウのサイズを ViewPort のサイズとして引き渡しているわけですね。

この情報はシェーダーで以下のように処理されている。

    out.position.xy = pixelSpacePosition / (viewportSize / 2.0);

Metal の使用する座標系を実際のウィンドウの大きさで割ることで、描画する図形の大きさを一定に保っているという理屈です。

単純に三角形を描画させたいだけであれば、頂点のデータは

    static const PHVertex triangleVertices[] =
    {
        // 2D positions,    RGBA colors
        { {  1.0,  -1.0 }, { 1, 0, 0, 1 } },
        { { -1.0,  -1.0 }, { 0, 1, 0, 1 } },
        { {    0,   1.0 }, { 0, 0, 1, 1 } },
    };

などと Metal 本来の座標系に準じて設定。
シェーダーも

    //out.position.xy = pixelSpacePosition / (viewportSize / 2.0);
    out.position.xy = pixelSpacePosition;

としてしまえば、三角形はウィンドウの大きさに従って変化します。

描画色に変化をつけてみる

私は試してないが、『シェーダーにランダムな値を送って動きをつける』あたりを参照して、改変するといいと思う。

ソースコードはこちらで。

回転させる、遠近処理をつける

詳しい解説はしないが、それなりの改変を加えると回転や遠近処理もできる。

その入り口くらいまではこちらの記事で軽く説明しています。
よろしければご一読ください。

 

 

DCMTK Ver 3.6.7

ちょっと前に twitter でも触れたのだが、DICOM 解析用のライブラリ DCMTK が Ver 3.6.7 にアップグレードされた。

このバージョンでは、ネイティブで arm Mac にも対応したので、早速、 M1 MacBookPro でビルド。

HorliX に組み込む

一部の機能を HorliX に搭載した。

ところで従来の HorliX のビルドシステムはお世辞にも洗練されているとはいえず、これを機会にかなり手を入れた。

ユニバーサルバイナリ(一つのバイナリファイルで Intel Mac と arm Mac で動作可能なファイルをこういう)まで一回のビルドでできれば申し分ないのだが、各種設定が面倒なため、当面は arm アーキテクチャにしぼって対応を進めていく予定だ。

(追記)やはり、ユニバーサルバイナリは、アーキテクチャ毎にビルドして、lipo コマンドで、それらを一つのファイルに落とし込む、というのが基本のよう。

デスクトップアプリ単体なら、一度に生成する、というのもなんとかなるかもしれないが、horlix のようにソースコードの大半がライブラリという場合は、やめておいた方がいいでしょう。

ライブラリとして使ってみる

知り合いの先生が、dcmtk を純粋にライブラリとして使ってみた例を提示している。(『DCMTK を Mac で使う』)

私も試してみたが、コマンドラインツールでは紹介されている方法でうまくいく。が、cocoa アプリでは(ビルド自体はできるが)実行させたときに、落ちるようだ。

最初、???だったのだが、どうやら、タグ解析時に使う dicom.dic がサンドボックスのせいで cocoa アプリから読み込めないのが原因のようだ。

解決方法は色々あると思うが、最も簡単なのはビルトインの辞書を使う方法だろう。

外部フォルダに置かれた辞書ではなくビルトインの辞書を使うためには CMake でライブラリを構築する際に ↓ のように

DCMTK_DEFAULT_DICT を builtin に設定する。

というわけで問題なく cocoa アプリから dcmtk が使えるようになった。
試しに実際のダイコムファイルから特定のタグ情報を抜いて、画像を表示させた。

コントラストがおかしいが、白黒反転すると正しくなりそう。

おそらく、US (Unsigned Short) の値を特に工夫せずにそのまま使うとこのようになる。

臨床的にはかなりまずいのだが、dcmtk 自体はうまく動いていると考えてよいのでまずは一安心。

クラスの階層構造

ところで、dcmtk は(多くのオブジェクト指向で書かれたライブラリがそうであるように)各クラスは階層構造を取っている。

上のサンプルでは、タグ情報を抜いてくるのに DcmDataset というクラスのメソッドを使ったが、このクラスの階層は以下の通り。

DcmDirectoryRecord は使ったことがないなあ。

まずは、興味の持てそうなクラスの主要なメソッドを試しに使ってみると次第に使い「慣れ」ていくようになると思う。

動画系は扱えるか

ここまで書いたついでで、動画系 dicom の話題。

dicom の転送構文(transfer syntax などという。訳語がいまいちピンとこないが)には、mpeg などの動画フォーマットも定義されている。

当然、dcmtk でもこれらのフォーマットが扱えないかが気になるところ。

海外でも同様の疑問は上がっているようだ。

現状だと「扱えなくはないが、安定性に欠ける」といったところでしょうか。

 

(続く)