HDKについて

Houdiniでは、`HScript`、`Python`、`VEX`、`C++(HDK)`の4つのプログラミング環境が使えますが、HDKはその中でも一番Houdiniのコアに近い所にある環境で、C++で記述して各種ノードのプラグインを作るものです。

この記事ではHDKを使ってプラグインをビルドするまでの導入部分を紹介したいと思います。HDK自体の解説についてはまた別の機会に、、、

## HDKの発見

僕が一番最初にHDKについて興味を持ったのは↓の動画を見たのがきっかけでした。

[Maya as Houdini Modeling tool :)](https://vimeo.com/14448626)

この動画では、Houdiniでメッシュの操作をするのがしんどいと思ったユーザーさんがMayaでモデリングをしてそのジオメトリのデータをHoudiniにリアルタイムで持っていけたぜ！的な所の紹介をされています。

そういうの自分もやりたい！と思い立ち、Pythonベースで[openFrameworksからジオメトリキャッシュを書き出し → Houdiniで読み込み](https://www.instagram.com/p/_NKsz5Bpgd/)というのをやってみたのですが、なかなかパフォーマンスが出ず。どうやったらもっと早くなるんだろうか、、、というリサーチを初めたのがそもそもになります。

その後はPython側でボトルネックになっていそうな所を[Cython](http://kesin.hatenablog.com/entry/20120306/1331043675)に書き直したりしたのですが、[色々やった結果HDKを使うのが一番早いのでは？](https://www.instagram.com/p/BAXkVoihpn0/)という結論に落ち着きました。

それらの試行錯誤の結果は、[この動画](https://www.youtube.com/watch?v=r_-m2VDwScA)の1:30あたりから、HoudiniからUnreal Engine 4にジオメトリを転送してリアルタイムレンダリングさせている部分に活用されています。

## 開発環境のセットアップ

さて、実際に動かす環境づくりの説明です。

注意点として、Houdini15.5からsidefxで公開されているHoudiniのビルド環境が変わりまして、15.5以前だとVC2012だったのが、以降だとVS2015でビルドされるようになりました。

それに伴ってHDKを使ったプラグインをビルドする環境も使用するHoudiniのバージョンにあわせる必要があります。

Houdini15.5以前で使われていたVS2012では、Houdiniが要求する64bitバイナリのビルドが無料で提供されている`Visual Studio Express 2012`だとできなくて、商用版の`Visual Studio Professional 2012`を用意する必要があります。

一方、VS2015の無料版、`Visuao Studio Community 2015`だと64bitバイナリも問題なくビルドできるので、**Houdini 15.5以降 + Visual Studio Community 2015環境を使うのがオススメの構成**です。

Visual Studio Community 2015 のダウンロード&インストールは → [こちらから](https://www.visualstudio.com/vs/community/)

インストーラーを起動してOKを押していれば特に問題なくインストールが完了します。(インストールが終わったら念のため再起動をしてください)

## HDKのサンプルを試してみる

まずsidefxが提供しているサンプルのビルドを試してみます。

ちょっと手順は違いますが、HDKのドキュメントの、[Creating Custom Plugins](https://www.sidefx.com/docs/hdk/_h_d_k__intro__creating_plugins.html)、`Building a Plugin: SOP_Star.C Example`を順を追ってやってみよう という感じです。

HDKのサンプルファイルは、`C:\Program Files\Side Effects Software\Houdini 15.5.XXX\toolkit\samples` あたりに入っているので、適当な所にコピーしてそれをいじるようにします。今回の場合、`C:\temp\samples`にまるごとコピーすることにしました。

### コンパイラにパスが通っているかの確認

[Visual Studio 用開発者コマンド プロンプト](https://msdn.microsoft.com/ja-jp/library/ms229859.aspx)を開いて、念のため `cl`や`nmake`などのVisual C++コンパイラのツール郡にパスが通っているかを確認します。

```
> cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]
```

などと表示されればOKです。

### Houdiniのツールにパスを通す

Houdiniには`hcustom`というHDKプラグインをクロスプラットフォームでビルドしてくれるツールが付属しています。まずはこれを使えるようにしてみましょう。

Visual Studio 用開発者コマンド プロンプトを開いた状態だと`hcustom`のあるディレクトリにはパスが通っていないので手動でこれを通します。

```
> set PATH=%PATH%;"C:\Program Files\Side Effects Software\Houdini 15.5.XXX\bin"
```

↑は環境変数の`PATH`に`hcustom`が入っているパスを末尾に追加するというコマンドです。(XXXの所は実行環境にあわせて適時置き換えてください)

```
> echo %PATH%
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow;
(...中略...);"C:\Program Files\Side Effects Software\Houdini 15.5.606\bin"
```

`echo %PATH%`を実行して、↑のように末尾にさきほど指定した文字列が追加されていればOKです。

パスが通っていれば`hcustom`と実行した時に↓のようなメッセージが出力されるはずです。

```
> hcustom
Usage: hcustom [OPTION]... { [FILE]... | -c | -m }
This program will make custom plug-ins (DSO's) for Houdini.

Options:
  -d           Display CFLAGS environment variable passed to hcompile
  -g           Create debug version of the DSO
(...略...)
```

### `SOP_Star.C`をビルドする

では、さきほど適当な所にコピーした`samples`の下の`SOP`フォルダに移動して`SOP_Star`をビルドしてみましょう。`cd`と`dir`コマンドを使います

```
> cd C:\temp\samples\SOP\
> dir
 Volume in drive C is Windows
 Volume Serial Number is 4878-70BC

 Directory of C:\temp\samples\SOP

12/11/2016  09:40 PM    <DIR>          .
12/11/2016  09:40 PM    <DIR>          ..
(...中略...)
09/21/2016  02:50 PM             8,409 SOP_Star.C
09/21/2016  02:50 PM             3,635 SOP_Star.h
(...中略...)
              57 File(s)        316,989 bytes
               2 Dir(s)  740,684,898,304 bytes free
```

`SOP_Star.C`が確認できました。

続けて`hcustom`コマンドでプラグインを作っていきます。単純に`hcustom`に続けてビルドしたいCファイルを入れればOKです。

```
> hcustom SOP_Star.C
Making 'SOP_Star.o' and 'c:/Users/satoruhiga//houdini15.5/dso\SOP_Star.dll' from 'SOP_Star.C'
SOP_Star.C
   Creating library SOP_Star.lib and object SOP_Star.exp
```

通常に終了すると自分のホームディレクトリの中、`$HOME\houdini15.5\dso`の中に`SOP_Star.dll`ができているはずです！

さらにHoudiniを立ち上げて`/obj`に入りタブを押したノードリストの中に`star`が追加されていると思います。

![MyFirstHDK.png](https://qiita-image-store.s3.amazonaws.com/0/38051/f5e234f4-48f6-94e9-de58-faef84851a8b.png)

HDKのサンプルの中にはStarの他にも色々なものがあります。興味がある方は色々とビルドして試してみてください！

*こちらの環境ではビルド時に`hcustom`がクラッシュしました。。。が、デバッグしますか的なダイアログに続けて開いたVisual StudioのウィンドウからBrake → Continueを選ぶと普通にビルドできて.dllもできていました。。謎。。。*

## まとめ - なぜHDKを使うのか

HDKのプラグインをビルドする所までを紹介てきたのですが、こんだけ色々やって星が出るだけじゃん… と思われた人もいるかもしれません。。ですが、HDKを使ってできる事、おそらくもっとあると思います。

例えば、

- `C/C++`の[大量のライブラリ郡](https://github.com/fffaraz/awesome-cpp)を使える
- 単純な速度比較でも`Python`と`C++`を比較すると[圧倒的にC++が早い](https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=python3&lang2=gpp) → 数倍~数百倍のオーダー
- 最初の例であったような、MayaなどのDCCツール、openFrameworksなどのリアルタイム系のツールなど、外部アプリケーションとの連携が高速にできる → Pythonでもできるけど、ボトルネックになりがち

あたりが挙げられると思います。

Houdiniはそれ自体がプログラミング環境かというぐらいにパワフルで自由度に富んでいますが、あと一歩の所で**自分の欲しかったものないじゃん、、**という経験をした事があるのではないでしょうか。

そういう時は大抵ノードの組合せでとんち的にごまかすか、Pythonなどを使って力技で解決すると思うのですが、そういった時にこそHoudiniが保持しているデータにフルアクセスできる`HDK/C++`の出番なのではないかと思います。

ものすごいめんどくさい事をする時に、簡単な処理なんだけどとにかく数がヤバいなどの時に、何かややこしい事があった時に、**Houdiniをもっと自由に使いたい時の最後の砦**として覚えておくときっと役に立つはずです！

## おまけ: VSのプロジェクトを自分で作ってサンプルをビルドする

おまけとして、`hcustom`を使うのではなくVisual StudioのIDEを使ってHDKプラグインを開発する方法をのせておきます。(僕は普段こっちのほうを使っています)

IDEを使う利点としては、

- いい感じに補完が入る
- 一回設定してしまえばコマンドラインをいじる必要がない
- Build & Runの手間が減る

あたりがあります。例として、さきほど紹介したものと同じ`SOP_Star.C`をビルドするプロジェクトを作ってみましょう。

(申し訳ないのですがVisual Studio英語版での紹介になります。。。)

---

### プロジェクトの作成、ソースコードの追加

![1-create_new_project.png](https://qiita-image-store.s3.amazonaws.com/0/38051/453887e4-d4e2-1ef6-5a60-2a86d36dbec5.png)

File > New > Project から新規プロジェクトを作成する
  
![2-create_project_1.png](https://qiita-image-store.s3.amazonaws.com/0/38051/73176048-b7ea-df82-a61f-56afdbd3d298.png)

左側から`Templates > Visual C++ > Win32`を選択して、真ん中の`Win32 Project`を選択、名前とパスを適当に設定して`OK`

![3-create_project_2.png](https://qiita-image-store.s3.amazonaws.com/0/38051/edcd0839-a9ee-f86f-638e-79c9d5b772a6.png)

ウィザードが立ち挙がるので↑の画像のようにして`Finish`

![4-setup_project_1.png](https://qiita-image-store.s3.amazonaws.com/0/38051/685f5907-417a-2342-38c6-eb3627e8b5b2.png)

新しいプロジェクトができるのでターゲットを `Release`, `x64`に設定する

![5-copy-source-file.png](https://qiita-image-store.s3.amazonaws.com/0/38051/e0e27951-a4f4-4867-0188-4605cbd13139.png)

プロジェクト以下に`src`フォルダを作り、ビルドしたいファイルをここにコピーしてくる。
その時に`.C`ファイルを`.cpp`ファイルにリネームしておく

![6-add-file-to-project.png](https://qiita-image-store.s3.amazonaws.com/0/38051/2ed4fa53-9c86-80b0-6869-6082e5497064.png)

さきほど作成した`src`フォルダをプロジェクトにドラッグ&ドロップで追加する
ここで一応ビルドを試してみると `SOP/SOP_Node.h` が足りないというエラーが出ると思います。HDKのファイル郡にパスが通っていないためです

### プロパティシートの導入

![7-show-propmanager.png](https://qiita-image-store.s3.amazonaws.com/0/38051/0d621e3b-648d-a0cc-0f62-38f00958dc33.png)

[HDKのビルドを簡単にするためのプロパティシート](https://gist.githubusercontent.com/satoruhiga/b243488e7582ee7086df8d64d9e138aa/raw/1a3738c8f1185b1f8b71aaca30d75e8d95c830f2/HDK.props)を作ったのでそれを追加します。
まず↑をプロジェクトのディレクトリにダウンロードしてきて `HDK.props` の名前で配置します

`Property Manager`を表示します。画面上に見付からない場合は`View > Other Windows > Property Manager` で表示してください。

`Property Manager`に表示されたプロジェクトを右クリックして、`Add Existing Property Sheet`を選択して、さきほど保存した`HDK.props`を指定します。

![9-setup-props.png](https://qiita-image-store.s3.amazonaws.com/0/38051/51616212-b0f9-2649-906a-408451de27fd.png)

`Release | x64`のドロップダウンの下にHDKという項目が追加されているはずなので、そちらをダブルクリックしてプロパティページを開きます。
続けて、`User Macros`の中の`HOUDINI_VERSION_BUILD`の数字を自分の環境のものと合わせて`OK`を押してください。

**!!! プロパティシートの内容を変更した場合、プロパティ名(この場合`HDK`)を右クリックして出る`Save HDK`を実行しないと変更した値が失われるので注意 !!!**

この状態でひとまずプラグインのビルドが状態になるとおもいますが、dllが書き出されるのがプロジェクトディレクトリの中の`x64\Release`の中になっているので手動で`$HOME\houdini15.5\dso`にコピーしないといけず効率が悪いです。。。続けてIDE上でBuild & Runできる設定をしましょう！

### 実行環境の整備

![10-setup-output-dir.png](https://qiita-image-store.s3.amazonaws.com/0/38051/4ddd8236-dac9-fd61-6623-95950cedefb0.png)

`Solusiton Explorer`のを開いて、`プロジェクト名を右クリック > Property`を表示します。続けて、`General > Output Directory`に`$(HOUDINI_USER_PREF_DIR)\dso` を指定します。

これで、ビルドした`.dll`が`$HOME\houdini15.5\dso`に配置されることになります。(ちなみに`HOUDINI_USER_PREF_DIR`は、さきほど追加した`HDK.props`の`User Macros`の中で定義されています)

![11-setup-debug-env.png](https://qiita-image-store.s3.amazonaws.com/0/38051/413df4be-357f-cd26-6434-5b002652d707.png)

さらにIDE上でBuild & Runできるように、`Debugging`の中の`Command`に`$(H)\bin\happrentice.exe`を、`Command Arguments`と`Working Directry`に任意のファイル名とディレクトリを指定します。

たとえば`Working Directory`に`$(ProjectDir)`を、`Command Arguments`に`untitled.hipnc`を指定すると現在のプロジェクトディレクトリにある`untitled.hipnc`を実行するという事になります。

ここまで設定できたら晴れてVisual StudioでF5を押したら立ち上がるといういつもの感じになります。おつかれさまでした！

現状の問題点として、`.dll`を`Release`ではなくて`Debug`でビルドして立ち上げた場合になんだかよくわからないけどエラーが出て起動しないというのがあります。。ここはちょっと追えてないのですが、このままだとまともにブレークポイントも設定できないのでどうにかしたい所。。。

おまけの方が有用な感じになってしまった感がありますが、これにて！