startでなければなりません。);```![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/40428ec2-ebc7-d09c-0626-2539b1cc38ad.png)ここでビルドします。フリーズ状態でboxが保持されていることが確認できます。##デジタルアセット入力したboxとデジタルアセットを接続してみます。そのために、まずはデジタルアセットの準備を行います。今回はテストなのでsubdivideとmountainのみのシンプルなHDAを作成します。![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/3077bfc6-7408-f4c6-544c-b52ac6d71b45.png)結果の確認![asset.png](https://qiita-image-store.s3.amazonaws.com/0/151589/d4386a66-a299-8c1b-9596-0a366a1b00ef.png)###HAPI_LoadAssetLibraryFromFile関数でotl・hda読み込みアセットを読み込んでノードのインスタンス化をする場合は、HAPI_LoadAssetLibraryFromFileでotl、hdaを読み込み、boxと同様にHAPI_CreateNodeします。デジタルアセットがObject/かSop/かどうかは適宜変更が必要です。);```今回は自分でデジタルアセットを作ったので、利用できる事もアセットの名前も自明でしたが、例えばotlを随時読み込んで処理するとなった場合はもうひと手間必要です。HAPI_LoadAssetLibraryFromFileを行った後にまず、HAPI_GetAvailableAssetCount関数でアセットライブラリに含まれるアセットの数を取得します。その後にHAPI_GetAvailableAssets関数を利用してotl、hdaでのString_Handle、アセットの名前を取得します。詳細については割愛します。###デジタルアセットと接続ノードを接続するためには先ほどboxとcopyの接続にも使用したHAPI_ConnectNodeInput関数を利用します。);```ビルド実行するとデジタルアセットのノードとInput用のノードが作成されていることが確認できます。![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/7201f4de-92e6-b494-8cee-c4bad2195cf5.png)HAPI_ConnectNodeInputによって、ObjectMergeが実行されています。先ほどboxとcopyをつなげた際は、同一ネットワーク内でしたが、今回は別のジオメトリを跨ぐためObjectMergeとなっています。![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/4a3581ae-cc9a-3b0a-f421-ace41c43c337.png)###デジタルアセットのパラメータ取得パラメータの取得や設定は、これまでやってきた方法と同じ方法です。パラメータをセットした後は忘れずcookを行います。HAPI_RESULT_SUCCESS);```mountainに大きい値が入ったので、ちゃんと変形が確認できました。![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/4407d7ab-a7a3-6815-95e4-bb204c72847b.png)この変更をホストアプリケーションに戻す場合は、HAPI_GetPartInfo関数で必要なAttributeなどの情報を戻します。HAPI_PartInfo戻り値)```##クリーンアップHAPI_PartInfoの情報をホストに戻すことで一件落着と、その前に忘れずセッションのクリーンアップをする必要があります。```C++:クリーンアップHAPI_Cleanup(&Session);```#QtのUIと紐づけせっかくQtを利用しているので、フォームに値を入れて戻る動作を確認します。mainwindows.uiをダブルクリックしてQtDesigner画面に遷移します。![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/ac1fba1c-1917-7a36-65b6-e6eabc715e47.png)![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/aa912d08-17f3-eb1e-be74-a8e9574b8bd5.png)-今回は-・height値を調整するパラメータエリア-・HoudiniEngineから戻って来た情報を出すDebug用のテキストエリア-+今回はサンプルなので、限定した機能として+・ノードを作成するボタン+・値を調整するパラメータエリア・Cookするためのボタン-を用意します。これを、otlを動的に変えたり、3Dビュー上で表示しながらHoudiniEngineのフィードバックを得る場合は、汎用的な設計が必要になるため割愛します。いうよりも僕の実力ではまだ作れません。公式のgitに上がっているプラグインや@K240さんが作成した[HoudiniEngineQt](https://github.com/K240/HoudiniEngineQt)を参考に設計をしていく必要があります。-![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/ba23d72d-44a0-2ba3-0a42-fd1b74fee814.png)+###main.cppから引っ越し+せっかく最後まで動いたところですが、このままだと実行のたびにすべての処理が走ってしまいます。+そこで、ボタンを押したらBoxだけ作成。パラメータを変更したら値にSet。処理ごとに仕分けをしていきます。+そのためにはmain.cppでは厳しいので、mainwindow.hとmainwindow.cppへ中身をごっそり持っていきます。+*あくまで今回のサンプルの作り方なので、ベストプラクティスはまた別に存在します。++まず、Clickボタンを配置します。+![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/bed95799-76b1-19bd-85ff-ec6cbee9b5b3.png)+そして右クリックでスロットに追加します。+![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/135bd47c-cb15-f072-6942-7a39fe0a2c64.png)++そうすると、mainwindow.hとmainwindow.cppに関数が追加されているので、必要な処理を追加します。+SessionやCookOptionsなどほかの関数でも流用する場合はmainwindow.hのクラス内でメンバを指定する必要があります。++あとは基本的に同じ動作を繰り返します。+HAPI_Cleanup(&Session);はmainwindowのデストラクタ内にひとまず置きました。++これでビルドを行えば完成です。+![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/0674a581-c0c9-e81d-c453-eb806fd6e7d0.png)以上、完成です。HoudiniEngineAPI入門いかがでしたでしょうか。簡単ではないけれども一切理解できない状態から、少しは霧が晴れたのではないでしょうか?2016年の@satoruhigaさんが紹介した[「HDKについて」](https://qiita.com/satoruhiga/items/49f8fa93307350e3c662)同様に、この技術がすぐに役に立つことはなかなか無いとは思います。HoudiniEngineAPIという外部からHoudiniの力を引き出せる強力な機能として、Hythonでは出来なかったホストアプリケーションとの連携や速度向上など様々なメリットがHoudiniEngineにはあります。この記事が皆様のお役に立てれば幸いです。次のアドベントカレンダーは@sugiggyさんの「失ったTransformを取り戻す。#補足ここでは、一連の流れで横道にそれるために省略した内容を補足としてまとめています。##補足:QtのインストールQtのダウンロードは以下の場所から行います。https://www.qt.io/downloadCommercial版とOpenSource版がありますが、今回はOpenSourceを選びます。Source![Ot1.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/5c3d2222-7892-6c74-d8da-996ba7157264.png)Nextとskipでどんどん進みます。Supportを選択します。![setup4.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/40e7fbd6-8615-c537-5184-b6abd4ed6486.png)どんどん次に進みます。![setup01.png](https://qiita-image-store.s3.amazonaws.com/0/151589/b50021bd-4d53-89c3-9e76-b2ebc7db9df4.png)ここで、数十分待てばインストール完了です。![setup9-1hlater.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/1a303bd7-b253-d93a-dc2c-cc3c8938df59.png)##補足:Qtのビルドインストールが完了したら、ビルドができるかを確認します。新しいプロジェクトをクリックしてプロジェクトを作成します。![newProject.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/be9b8893-7e3f-e010-0d7d-3811afee12a0.png)ここは好みだとは思いますが、今回はQtウィジェットアプリケーションを選択します。![newProject2.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/11c930b4-b8f0-ad12-85f2-22c6a736c8a4.png)プロジェクトの名前とパスを入れます。64-bitを選択します。![newProject4.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/53f2e6ab-1bc0-7813-dff2-58355d64201b.png)クラス情報とプロジェクト管理はそのままに、完了します。![newProject5.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/991f6fab-3828-9ad0-d9f1-8ce7f2a78a41.png)![newProject6.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/52dd951b-4e10-ed55-beb5-401fb24600cc.png)main.cpp含むフォームが出るだけの初期状態プロジェクトが表示されました。![newProject7.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/6bb5a254-1d78-5581-b62f-fa8c6af14802.png)ビルドが走るかを確認します。![build.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/00894109-d493-da6a-9042-d857db0cfcb9.png)完了したら、実行させます![run.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/6578d6a0-c6fe-28c8-b87e-ba0e96449706.png)これで空っぽのフォームが出てくれば、ビルドは成功しています。##補足:バージョンの確認Houdiniエンジンを使用してアプリケーションを作成する場合、環境変数を間違ってしまいHoudiniエンジンの他のバージョンを指してしまう可能性があります。Engineのバージョンであることを確認する必要があります。*自明の場合は不要です。*value)を利用します。14```となり、メジャーバージョンが16、マイナーバージョンが5、ビルドバージョンが571。HoudiniEngineのバージョンは3.1であることがわかります。HAPI_Versionを他から参照する場合はHAPI_GetEnvInt関数で欲しいバージョンを引数として、値を取得します。%d",Version_H_Major,Version_H_Minor,Version_H_Build);```HoudiniEngineのバージョンによって、関数の引数が変わることがあります。よって、昔のコードをそのまま持ってきても使えないケースが出てくることがあります。その場合は、ドキュメントを参照して型に合った値を入れなければなりません。HoudiniEngine3.1に変わったときに大きな変更があったようです。##補足:環境変数Houdiniエンジンは、初期化時に次の環境変数を探します。**HAPI_LICENSE_MODE:**デフォルトではHoudiniEngineが最初にHoudiniEngineライセンスを検索し、見つからない場合は、Houdiniライセンスを取得します。どちらかのライセンスのみ取得する設定も可能です。'2.7'に設定します。これは、主にWindows上でホストPythonバージョンとHoudiniのPythonバージョンとの間で衝突する場合に便利です。**HFS(HoudiniFileSystem):**Houdiniインストールフォルダのパスを設定します。この変数は、HAPI_Initialize()またはHAPI_CreateInProcessSession()を呼び出すときにHAPI.dllを見つけるために使用されます。HoudiniEngineが文字列をホストアプリケーションに返す場合、HoudiniEngineは文字列を直接処理しません。その代わりに、呼び出し元関数は返す文字列に**HAPI_StringHandle**を渡します。**HAPI_GetStringBufLength()**を呼び出して、文字列を保持するために必要なバッファのサイズを取得。適切なサイズのバッファを割り当てた後、**HAPI_GetString()**を呼び出しせば文字列を取得できます。###戻り値HAPI_Resultとエラー文字列HoudiniEngineのすべての関数は、**HAPI_Result**の値を返します。**HAPI_RESULT_SUCCESS**以外の戻り値は、何らかの形式の失敗を示します。最初に**HAPI_GetStatusStringBufLength()**を呼び出し、次に**HAPI_GetStatusString()**を呼び出すことによって、問題の詳細を得ることができます。今回は標準入出力を出すのに工夫がいるQtを利用したため割愛しましたが、SideFXのドキュメントではstd::stringでのデバッグを推奨しています。\}```HAPI_ResultがSUCCESSでないとき以下の関数を呼び出します。result;}```実際にHAPI_RESULTが知りたい関数などに対してENSURE_SUCCESSでエラー確認を行います。);```詳しく知りたい方は、SideFXドキュメント内のSmapleに詳しく乗っているので、そちらを参照してください。[SideFXドキュメント内のSample](https://www.sidefx.com/docs/hengine/_h_a_p_i__full_source_samples__compiling_samples.html)###BreakPointではQtでデバッグする場合はどうするかというとを利用するのでBreakPointを利用するのが最も楽にデバッグが可能です。コードの左を左クリックすることでBreakPointの作成が可能です。![breakpoint.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/2232a8c5-c69a-51e6-4394-42b9e63a8a3a.png)この状態でデバッグすると![debugPNG.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/8cbab5ad-4b2b-39ac-1391-f041f535f3d1.png)BreakPoint時のパラメータ参照が可能です。![debug2.PNG](https://qiita-image-store.s3.amazonaws.com/0/151589/a13066b9-5137-02ea-8c65-aeacc90d5542.png)##補足:その他のノードのパラメータ問い合わせノードIDを取得した後は、HAPI_GetNodeInfo関数を利用してノード情報にアクセスする必要があります。HAPI_GetNodeInfo関数の呼び出し時にHAPI_NodeIdを指定すると、HAPI_NodeInfo構造体を埋めることができます。アセットを取得する場合:**HAPI_GetAssetInfo()**を使用して**HAPI_AssetInfo**を取得。オブジェクトを取得する場合:**HAPI_GetObjectInfo()**を使用して**HAPI_ObjectInfo**を取得。ジオメトリを取得する場合:**HAPI_GetGeoInfo()**を使用して**HAPI_GeoInfo**を取得。マテリアルを取得する場合:**HAPI_GetMaterialInfo()**を使用して**HAPI_MaterialInfo**を取得。**HAPI_NODEFLAGS_EDITABLE**、**HAPI_NODEFLAGS_NETWORK**、**HAPI_ComposeChildNodeList()**を使用して編集可能なノードネットワークのリストを問い合わせることができます。Propertiesの設定でEditableNodesを指定することでパラメータが編集可能になります。![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/102517ea-036a-26ac-6cca-8e580f969147.png)##補足:ライセンスHoudiniエンジンは、これらのライセンスが見つかるまで、次の順序でこのライセンスをチェックします。Apprentice)はサポートされていません。**さらに、ティアリングは、HoudiniEngineでは許可されていません。lc)アセットを実行することはできません。Indieアセットを実行するには、Indieライセンスをチェックアウトする必要があります。下位層ライセンスは、上位層ライセンスで作成されたアセットを実行できます。Indieライセンスで動作するHoudiniEngineは、商用アセットを実行できます。**Indieライセンスの使用は、承認されたプラグイン(Unity、Unreal、Maya、Max、C4D)に限定されます。**###ライセンスチェックHoudiniエンジンは、以下の2パターンのAPIコール中に有効なライセンスを確認します。Node**![image.png](https://qiita-image-store.s3.amazonaws.com/0/151589/1f938c83-6a6b-df7c-da21-30e77cb330c7.png)ライブラリファイルのロード中に、有効なライセンスが見つからない場合は、次のHAPI_Resultを取得できます。ライセンスが見つかりませんでした。サポートされていない非商用ライセンスのみが見つかりました。|ノードの作成中に、次のHAPI_Resultのライセンスに関する情報を取得できます。ライセンスが見つかりませんでした。HAPI_RESULT_DISALLOWED_NC_LICENSE_FOUND|サポートされていない非商用ライセンスのみが見つかりました。HAPI_RESULT_DISALLOWED_NC_ASSET_WITH_C_LICENSE|汚染している間は認められません、非商業アセットは商用ライセンスでは稼動できません。HAPI_RESULT_DISALLOWED_NC_ASSET_WITH_LC_LICENSE|汚染している間は認められません、非商業アセットは限定商業ライセンスでは稼動できません。|汚染している間は認められません、限定された商業アセットは商用ライセンスでは稼動できません。|Indieライセンスは、承認されたプラグインでのみ使用できます。2013年にSIDEFXLabsで開発され発表されました。[SideFXドキュメント内のSample](https://www.sidefx.com/docs/hengine/_h_a_p_i__full_source_samples__compiling_samples.html)以下の場所にあります。(見つけにくい!)![here.png](https://qiita-image-store.s3.amazonaws.com/0/151589/81d3b928-8ca7-12d2-1753-164416a7d60a.png)-[@K240さんが作成したHoudiniEngineQt](https://github.com/K240/HoudiniEngineQt)+@K240さんが作成した[HoudiniEngineQt](https://github.com/K240/HoudiniEngineQt)インストールしたディレクトリ内にもサンプルがあります。Mayaについての記事を作成されています。99米ドルで提供していましたが、無償となりました。インストールは以下の場所から可能です。Engineはレンタルライセンスで購入する必要があります。Licenses(ノードロック)の場合スタジオでのライセンスの使用は5ライセンスまでに制限されています。代理店での購入はそれぞれ最低オーダー数が存在します。25本以上の購入はアカウントマネージャーに連絡してください。*価格は2018年12月時点のものです。Borndigitalhttps://www.borndigital.co.jp/software/houdini-engine.html※価格は税別です。