<< TOP



カスタム ICEノード の作成 ; ICE SDK Wizards
Making ICE Custom Node
(プログラマー・TA向け)






 プロローグ
      今回、CEDEC2011にて ICEプレゼンを行い、
    独自のICEノードでデータをSoftimageに読み込んで来る様子を紹介しました。
    で、質問は、カスタムなICEノードを作成するSDKが存在するのか? でした。
     答えは ハイ、なんですが、SoftimageのPlugin製作と同様に、
    便利な ウィザード が存在します。
    ここでは、PCにC++コンパイル環境の設定 ICE SDK Wizards を使って
    DLLプラグイン形式の カスタムICEノード の作成方法を紹介します。

    > 前準備 環境設定
      > コンパイル環境
    > サンプルデータ
      > Vector3Union
    > SDK_Wizards
      > ICENodeWizardPPG
    > VC++ 2008 上の作業
      > コンパイル
    > 動作確認
      > 試行錯誤

パソコンのスペック WindowsXP SP3、 Intel Core2Duo 3G、 RAM; 3G、NVIDIA Quadro FX1700



前準備 環境設定
 コンパイル環境
     まずは、Softimage SDK プログラミング ガイド > C++ API 開発 > C++ プラグインのビルド >  
    から プラグインのコンパイル を見てみると、

    推奨セットアップ

        Windows の場合、推奨開発環境は Visual Studio 2005 SP 1 です。
        プラグイン ウィザードを使用して、Visual Studio 2005 SP 1 のプロジェクトを作成します。
        ただし、現在も Visual Studio 2008 で v2011-SP プラグインをコンパイルできます。

     と書かれていますので、間違っても VisualStudio2010 で挑戦しないでください。(変換がうまくいきませんですし)

     で、ここでは実験で、個人プロジェクトの範囲のテストなので、VisualStudio2008Express で行ってみます。
      (商業利用の場合は、ちゃんと買ってね)

        Visual Studio 2008 Express Edition with Service Pack 1 のダウンロード
         http://www.microsoft.com/japan/msdn/vstudio/2008/product/express/
        から Visual C++ 2008

         の >Web インストール (ダウンロード) からインストーラーをダウンロードして、vcsetup.exe をインストールします。
        そのままでは28日間の無償利用なので、30日以上無料の登録をします。
        登録をすると登録キーが送られて来るので、それを [製品の登録] >[登録を完了する] をしておきます。

    Windows でプラグイン をコンパイルする
       
        バッチ ファイルを使用して Visual Studio の設定および起動を行うと、
        ビルド エラーやリンク エラーを回避した、 XSISDK_ROOT などの環境変数が適切に設定されます。
        これは、バッチ ファイルが Softimage コマンド プロンプトを開いて Visual Studio を起動するシミュレートを行うからです。

     と書かれているので、そのバッチファイルを作成しましょう。
    PC は 32bit で、Softimageのバージョンは 2012SP1 とします。

    32 ビット環境で Softimage x86 プラグインをコンパイルする

    の項目を参照します。バッチファイルの名前は VC32XSIx86.bat にしたとします。

     Visual Studio 2008 の場合は、 VC32XSIx86.bat の中身はこうなります。

        @echo off

        call "C:\Program Files\Autodesk\Softimage 2012 SP1\Application\bin\Setenv.bat"
        call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86

        set PATH
        set XSISDK_ROOT="C:\Program Files\Autodesk\Softimage 2012 SP1\XSISDK"

        "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe" /useenv

        echo on

    ところが、VisualStudio2008Express では、devenv.exe が無いんですよね。で

        @echo off

        call "C:\Program Files\Autodesk\Softimage 2012 SP1\Application\bin\Setenv.bat"
        call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86

        set PATH
        set XSISDK_ROOT="C:\Program Files\Autodesk\Softimage 2012 SP1\XSISDK"

        "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\VCExpress.exe" /useenv

        echo on

    とすれば 良いです。
    どっちでもいいようにするには、こんな感じでしょうか。

        chdir "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE"
        if exist "devenv.exe" devenv.exe /useenv
        else if exist "VCExpress.exe" VCExpress.exe /useenv


     用意したバッチファイル VC32XSIx86.bat は 
    Softimageのバージョンのコマンドプロンプトのディレクトリーで実行させますので、今回は、
    C:\Program Files\Autodesk\Softimage 2012 SP1\Application\bin 以下に置きます。



    プログラム>Autodesk>AutodeskSoftimage2012SP1(32Bit)>ComandPrompt で開き
    VC32XSIx86 を実行して Visual Studio が起動したら 準備はOK♪ です。


            起動する


     あとは、このバッチファイルのショートカットを作成して デスクトップにでも置いて、
    アイコンも好きなものに変えておけば、いつでも ここからSoftimageの環境の通った Visual Studio が起動できます。



    追加情報 もし、VisualStudio2008Express 64BIt版をコンパイルしたい場合、なんと The Softimage Wiki に情報がありました。
        参考にしてみてください。 (C++ 2010 Express:情報もあります、うまくいくのか?)
        http://softimage.wiki.softimage.com/index.php/Cpp_64_bit_Visual_CPP_Express%28XSISDK%29



サンプルデータ
  Vector3Union
    まずは、標準で用意されているサンプルデータから始めると良いです。
    Softimage SDK まわりのサンプルのワークグループは、 
    C:\Program Files\Autodesk\ <バージョン> \XSISDK\examples\workgroup にあります。
    具体的には、今回は
    ファイル>プラグインマネージャー から
      C:\Program Files\Autodesk\Softimage 2012 SP1\XSISDK\examples\workgroup を指定します。



     色々と実験をする時は このワークグループ を設定すると色々なサンプルが読み込まれます。
    必要無くなったら、ワークグループからチェックを外せば良いだけです。

     今回は、ICEのカスタムノードなので、そのサンプルデータは
    C:\Program Files\Autodesk\Softimage 2012 SP1\XSISDK\examples\workgroup\Addons\CustomICENodes
    内にあり、
    ソースは 各ツール名の中、
    シーンデータは
    C:\Program Files\Autodesk\Softimage 2012 SP1\XSISDK\examples\workgroup\Addons\CustomICENodes\Data\Project\Scenes
    にあります。
     例として vector3_union を取り上げたいと思いますので、Vector3Union.scn というシーンを開きます。



     シーンを開いて再生すると、
    パーティクルが発生して 2つのNullに範囲内に入って来た点に、色とサイズを設定した新たな点を追加する、
    というものですが、2つNullがあるので、
    vector3_union というカスタムなICEノードで  2つの3DVectorを合成している
    というものです。



SDK_Wizards
 ICENodeWizardPPG
     では、このカスタムICEノード vector3_union SDK_Wizards を使って作成する手順を紹介します。



     ファイル>プラグインマネージャー を開き、
    ユーザールート > プラグイン > 新規作成 > ICEノード を選択します。

       ちなみに、ユーザールート というのは 
         C:\users\ <ユーザー名> \Autodesk\ <バージョン> \Application\Plugins 
      内のことで、
      今回の具体的例では、
      C:\users\ritaro\Autodesk\Softimage_2012_SP1\Application\Plugins 内にプロジェクトファイルが書き出されます。(変更可)
       (あれ、GnuのMakeファイルまであるよ、と思った方、ハイそうです、Linuxでのコンパイル用です。)

     以下の ICENodeWizerd のもっと詳しい情報は、
    Softimage SDK プログラミング ガイド > SDK によるカスタマイズ > カスタム ICENode > カスタム ICENode ウィザード
    に書かれていますので参照してください。

     すると、自動的に設定画面 ↓ が表示されるので、ここに各種設定を入れていきます。


    まず ICENode情報 タブには 



      タイプVector3UnionNode
      UI名Vector3Union  ICETree上に持って来た時のノードの名前
      カテゴリーCustom ICENode ICETreeの左側の検索項目内に入る カテゴリーの名前
      処理モードsiICENodeMultiThreading (デフォルト)
      カラー ICEノードの色
      製作者(任意に)
      コーディング言語[CPPしかない]
      出力ディレクトリー(ユーザールート;コンパイル環境先でも良い)

    と、同時に、エクスプローラー上では SDK_Wizrds というモデルの中に [C] ICENodeWizard というノードが作成されています。
    設定画面を閉じてしまっても、このノードから開けますし、シーンを保存してもノードは残っています。


    入力ボート タブは 左側の入力接続部の設定を作ります。



      入力ポートの名前InArray1
      データタイプsiICENodeDataVector3
      構造タイプsiICENodeStructureArray
      コンテキストタイプ siICENodeContextComponent0D|siICENodeContextSingleton
      ↑後で下の行で追記する
      コンストレイントポートタイプOFF
      グループID100 (デフォルト)

    などを右の三角から開いたメニューから選択するのですが、 
    最後の コンテキストタイプは 下の行を作ってから |siICENodeContextSingleton を追記しています。

    項目は データタイプ で選んだ種類によって変化します。
      例えば、siICENodeDataFloat を選択すると、下に UIの範囲指定が表示されます。

     記入したら、[追加] っていうボタンを押すと 下に設定情報の行が表示されます。
    ここでは、左側に同じ種類の2つのポートを作成するので、
    InArray1 ポート名で [追加] のボタンを押し、
    InArray2 ポート名でもう一回 [追加] ボタンを押して、2行を作成します。
    PortIDは上から 0 と  になっています。


     出力ボート タブは 右側の出力接続部の設定を作ります。
    入力ポートの時と同じで メニューから選択します。



      出力ポートの名前result
      データタイプsiICENodeDataVector3
      構造タイプsiICENodeStructureArray
      コンテキストタイプ siICENodeContextComponent0D|siICENodeContextSingleton
      ↑後で下の行で追記する
      コンストレイントポートタイプOFF

    最後の コンテキストタイプは 下の行を作ってから |siICENodeContextSingleton を追記しています。

    result ポート名で [追加] のボタンを押して 1行を作成します。


     コード タブは いよいよ 作った内容を CPP として書き出します。



      サンプルコードの追加ON

     サンプルコードの追加 にチェックを入れると、各関数の開始部分に、ブロックのコーディング方法を説明する便利なコメントが書かれます。

    [コードの生成] ボタンを押すと
    Vector3UnionNode.cpp と Vector3UnionNode.vcproj を ユーザールート に出力します。何度でも・・・・

VC++ 2008 上の作業
 コンパイル
     上記 SDK_Wizards で作成されたのは枠であって、プログラム部分の追記が必要です。
    作った VC32XSIx86.bat のショートカットから VisualStudio2008Express を起動し、
    作成された プロジェクトファイル Vector3UnionNode.vcproj を開きます。

     まず、 #include の最後に 

      #include <algorithm>

    を追記します。
    そして、125行からの

      // Add code to set output port...

      CDataArray2DVector3f::Accessor InArray1SubArray = InArray1Data[it];
      for (ULONG i=0; i<InArray1SubArray.GetCount( ); i++)
      {
      Application().LogMessage( CString( InArray1SubArray[i] ) );
      }

      CDataArray2DVector3f::Accessor InArray2SubArray = InArray2Data[it];
      for (ULONG i=0; i<InArray2SubArray.GetCount( ); i++)
      {
      Application().LogMessage( CString( InArray2SubArray[i] ) );
      }

    部分を

      // Add code to set output port...

      CDataArray2DVector3f::Accessor a1 = InArray1Data[it];
      CDataArray2DVector3f::Accessor a2 = InArray2Data[it];

      // Sort arrays in place
      ULONG nCount1 = a1.GetCount();
      ULONG nCount2 = a2.GetCount();
      std::sort( &a1[0], &a1[0]+nCount1 );
      std::sort( &a2[0], &a2[0]+nCount2 );

      // Resize out to max array
      CDataArray2DVector3f::Accessor out = outData.Resize( it, nCount1 + nCount2 );

      // Union of a1 + a2
      MATH::CVector3f* pLast = std::set_union( &a1[0], &a1[0]+nCount1, &a2[0], &a2[0]+nCount2, &out[0]);

      // Resize out with number of elements in union
      ULONG nOutCount = (ULONG)(pLast - &out[0]);
      outData.Resize( it, nOutCount );

    と書き換えます。



    ビルド を実行して コンパイルが無事通ります。

     出来上がった Vector3UnionNode.dll は 54KB ありました。もちろんこの状態で動作します。
    デバッグ時にトレースできるようないろいろな情報が入った状態、ビルドがデバッグで実行されています。
    下の動作確認が済んだら、ビルド > 構成マネージャRelease に設定してコンパイルすると 20KBになりました。
      <Softiamgeが立ち上がっていて dllがロードされていると 失敗 しますので、Softimageを落とすか アンロードするかしてから リコンパイル です。>

動作確認
 試行錯誤
     今、SDKのサンプルプログラムを作り直していて、重複すると混乱するので、
    ファイル>プラグインマネージャー から設定した
    C:\Program Files\Autodesk\Softimage 2012 SP1\XSISDK\examples\workgroup 
    のチェックを外して、ワークグループ設定を解除しておきます。

     作成したプラグインを読み込みます。



     ファイル>プラグインマネージャー で [すべて更新] ボタンを押すと、プラグインの下に現れます。
    何度か試したりする場合、ここから アンロード とすれば 登録から消えます。
    リコンパイルは アンロードしてから 行わないと 上書きが禁止になってしまいます。



     [すべて更新] ボタンを押した時に ICETree 内もリフレッシュされ、
    SDK_Wizards で 指定した カテゴリー名 Custom ICENode に、コンパイルした ICEノード Vector3Union が置かれています。
    左アイコンに U と書かれているのは、このノードが ユーザールート の中にあることを示しています。(W はワークグループ)
    正常動作するか確認します。

    何度かやる場合は、ここら辺の繰り返しになります。




     という訳で、まだまだ ICE が続きます。

      乞う、ご期待!!