2020-03-24

vexpression-backticks

Height Field を作成し、その出力に HeightField Wrangle を追加。VEXpression に

@mask = 1;     // A
とすれば、マスク全体が 1 に設定される。

VEXpression を ` (バックティック) を使って以下のように変更しても問題なく評価される。

@`"mask"` = 1;    // C

また chs で layername パラメータを作成、そのパラメータを mask と定義し、VEXpression を 以下のようにしても問題なく評価される。

@`chs("layername")` = 1;    // D

しかし以下のエクスプレッションでは、構文は正しくとも、マスクは期待通りに設定されない。

string layername = "mask";
@`layername` = 1;    // B

B が想定通りに評価されない理由を以下に説明する。

使用したビルド: Houdini 18.0.491 (Windows 10)
シーンファイルへのリンクは一番下にあり。

VEXpression でのバックティック

  1. ` (バックティック) で囲んだ部分は、Unix でのコマンド置換同様に機能
    よって、
    1. 二つのバックティック間のコマンドを評価
    2. その結果が文字列としてコマンドを置換
    となり、例えば、
    `"mystring" を返すコマンド`

    mystring
    で置き換えられる。
  2. バックティック間で使えるのは HScript 関数の構文のみ
    これがそもそものまごつきの原因の可能性があるが、例えば、上の D にある chsは、Hscript 関数でもあり VEX 関数でもある。実際には、
    1. Hscript chs が評価され
    2. その結果が VEX スニペットとして挿入される
    3. このスニペットがコンパイルされ実行される
  3. "VEXpression" ラベルを MMB クリックすることで置換を視認可能
      例えば D が書かれた Volume Wrangle ノードの "VEXpression" ラベルを MMB クリックする。

      すると、バックティック間の置換後の結果に置き換わる。

      元に戻すには同じ場所をもう一度 MMB クリック。
  4. この要領で見れば、B の例
    string layername = "mask";
    @`layername` = 1;    // B
    string layername = "mask";
    @layername = 1;
    と置換されていて、これではうまくいかないことがわかる。

VEX バインディング

Bindings タブで layername と mask をバインドすることで B の VEXpression を期待通りの挙動にすることが可能。Volume Wrangle ノードの Bindings タブに行き、

  1. Autobind by Name をオフ
  2. Number of Bindings を 1
  3. Primitive Name に mask
  4. VEX Parameter に layername
とすれば、B の VEX 関数であっても期待通りの挙動に変更可能。

まとめ

0 件のコメント:

コメントを投稿