On this page |
概要 ¶
パラメータ内に数式のような短いコードを入力して、数学や、現行フレーム番号、ポイント番号、乱数などの変数を使用して値を計算することができます。 例えば、手動でキーフレームを打つことなく時間軸で球を上昇させるには、その球のY座標にフレーム番号を5で割った式を設定することで可能です。
言語 ¶
Houdiniは2つの異なる言語:従来のHScriptエクスプレッションとPythonでエクスプレッションを記述することができます。さらに、特定のノードではVEXスニペットを記述することで、そのノードの挙動を制御することができます。
HScriptエクスプレッション |
エクスプレッションを記述するための従来の方法。エクスプレッション関数を使用します。 |
Python |
エクスプレッションを記述するための強力で冗長な方法。Houdini Object Model APIとPythonビルトイン関数を使用します。 |
VEX |
高速なコンパイル言語。特定のノードの特定のパラメータでのみ利用可能です。 |
デフォルトでは、Houdiniのパラメータは上記で説明している従来のHScriptエクスプレッション言語を使用します。 特定のパラメータ、ノード、またはすべてにPythonを使用するように切り替えるには、Pythonパラメータエクスプレッションを参照してください。
HScriptエクスプレッションのサンプル ¶
-
新しくGeometryオブジェクトを作成して、中に入ります。
-
Gridノードを作成します。
-
パラメータエディタで、Gridノードの Size フィールドを以下に設定します:
$F / 10
これは、現行フレーム番号を基準にグリッドのサイズを決めます。メインウィンドウの下にあるプレイバーを使ってアニメーションを再生してみてください。
文字列パラメータ ¶
-
数値パラメータ (例えば、位置、回転、スケール)では、そのパラメータ内のテキストはエクスプレッションとして評価されます。
-
文字列パラメータ (例えば、ファイル名やFontノードで作成するテキスト)では、そのパラメータ内のテキストはテキストとして扱われます。変数は展開されますが、数学やエクスプレッションを使用してテキストの部分を生成するには、バッククォートでエクスプレッションを閉じなければなりません。例:
frame`padzero(5, $F)`.pic
…これは、ファイル名が
frame00001.pic
、frame00002.pic
などになります。
(ファイル名パラメータに変数とエクスプレッションを使用する方法の詳細は、ファイル名のエクスプレッションを参照してください。)
変数とアトリビュート ¶
エクスプレッションには、Houdiniで用意された変数を使用することができます:
-
$F
(現行フレーム番号)や$T
(単位が秒の現行時間)などの グローバル変数 。以下のグローバル変数のリストを参照してください。 -
ジオメトリアトリビュート 。ジオメトリに対するHScriptエクスプレッションでは、
@attributename
を使ってアトリビュートの値を参照することができます。例えば、@pscale
を使えば、現行ポイントに対するpscale
(point scale)アトリビュートの値を取得することができます。P
(ポジション)などのベクトルアトリビュートに関しては、ドット表記(例えば、@P.x
)を使用することでコンポーネントを取得することができます。これには.x/.y/.z
、.1/.2/.3
、.r/.g/.b
を使用することができ、どれもデータのタイプで理にかなった表記になっております。 -
ローカル変数 。ノードには、そのタイプのノードのエクスプレッションで役に立つ変数が用意されていることが多いです。例えば、ジオメトリ内のポイントに対して処理をするノードには、現行ポイントのポイント番号を意味する
@ptnum
変数があります。ノードのヘルプには、そのタイプのノードのエクスプレッションで使用可能なローカル変数のリストが載っています。 -
$HIP
(シーンファイルを含んだディレクトリ)などの 環境変数 がエクスプレッションで利用可能です。
パラメータ/チャンネルの参照 ¶
HScriptエクスプレッションでは、ch関数を使用することで、ノードのパラメータの値を参照することができます。これは、あるノードが追従する数値を作成したり、他のノードの数値を基準にした数値を作成するのに役立ちます。
Tip
独自のパラメータを作成して、それをエクスプレッションで参照することができます。Spareパラメータ(ユーザパラメータ)を参照してください。
To... | Do this |
---|---|
自動的にチャンネル参照を作成する |
|
手動でチャンネル参照を作成する |
HScriptエクスプレッションをタイプする時、ch関数を使用して他のパラメータの値を取得します。
ch("tz")
ch("/obj/lamp/tx") 現行ノードと同じネットワーク内の ch("../grid1/ry") (文字列値を取得するには、chsを使用します。) |
パラメータの内部名を調べる |
手動でパラメータを参照するには、そのパラメータの内部名を知らなければなりません。これはパラメータラベル上にマウスカーソルを置くか、または、パラメータエディタ内の ▸ Edit Parameter Interface をクリックし、そのパラメータをクリックして、その Name フィールドで知ることができます。 |
複数行にわたるエクスプレッション ¶
通常では、エクスプレッション言語は、パラメータ値と他の値との関係性を表現した短い1行の式(例えば、X位置に$T * 2
を設定してボールを動かすことができます)を記述するのに使用します。
パラメータエクスプレッション内に複雑なスクリプトを組みたい場合、パラメータが従来のエクスプレッション言語の代わりにPythonを使用できるようにしたいことがあります。
とはいえ、従来のエクスプレッション言語を使って複雑なことをしたい場合、ブロック、if
ステートメント、for
ループを使用して、複数行にわたるエクスプレッションを記述することができます。
Tip
HScriptエクスプレッションとPythonエクスプレッションのどちらでも、パラメータ内で⌃ Ctrl + Eを押すか、または、パラメータを右クリックして Expression ▸ Edit Expression を選択することで、マルチラインフローティングエディタが開いてエクスプレッションを記述することができます。
-
ブロックとは、波括弧(
{
と}
)の中に一連のサブステートメントを記述したものです。 -
サブステートメントはセミコロン(
;
)で区切る必要があります。 -
サブステートメントは以下のように構成することができます:
-
割り当て。割り当ての右辺には、エクスプレッション構文と関数を使用することができます。変数名の前にその変数の型(
float
またはstring
)を指定しますが、 floatの場合は任意 で、 stringの場合は必須 です。例:
size = 0; float frame = ch("outputframe"); string name = ch("name");
{}
ブロック内で割り当てられた変数は、ローカル変数となります。 -
j += 5;
やi -= 1;
といったその場の修正、i++;
やj--;
といったCスタイルのその場の増分/減分をステートメントとして使用することもできます。 -
if...then...else
ステートメント。以下のifステートメントを参照してください。 -
for
ループとwhile
ループ。以下のforループを参照してください。 -
return
ステートメント。return
の右側には、エクスプレッション構文と関数を使用することができます。return
ステートメントが実行されると、そのエクスプレッションが評価され、{}
ブロックの最終値として使用されます。return
ステートメントは最後でなくても複数箇所に記述することができ、例えば、if
ブロック内に記述することができます:{ # ... if (evalmode == 4) { float slope = (ch("../inputrangey") - miniframe) / (ch("../outputrangey") - minoframe); return miniframe + ($FF - minoframe) * slope; } # ... }
(
return
ステートメントが実行されなかった場合、外側{}
ブロックは0
と評価します。) -
#
文字は1行コメントを開始します。#
文字以降の1行は無視されます。
-
ifステートメント ¶
Note
エクスプレッション言語には、以下の形式のif関数を使用することができます:
if(expression, true_value, false_value)
if
ステートメント とif
関数 の違いは、上記のif
関数 では、条件エクスプレッション、Trueエクスプレッション、Falseエクスプレッションはどれも常に評価されることです。
以下で説明しているif
ステートメント では、条件エクスプレッションが評価されてから、その真偽に基づいて分岐のどちらかのみが実行されます。
マルチラインエクスプレッションのif
ステートメントはC言語に似ています:
-
if
の後には、丸括弧(()
)を付けて、その中にブーリアンエクスプレッションを記述します。 -
エクスプレッションがゼロ以外の値(“true”と判断)に評価された場合に実行されるステートメントまたはブロック(
{}
内のステートメントグループ)を記述します。 -
前の分岐が実行されなかった場合に次に実行されるオプションの
else if (expr) stmt
分岐を記述します。 -
これまでの分岐が実行されなかった場合に実行されるオプションの
else stmt
分岐を記述します。
{ size = 0; if ($F > 10) { size = 23; } else if ($F > 20) { size = 47; } else { size = 50; } return size; }
forループとwhileループ ¶
マルチラインエクスプレッションのfor
ループはC言語に似ています:
-
for
の後には、丸括弧(()
)を付けて、その中にセミコロン(;
)で区切った3個のエクスプレッションを記述します。例えば、(i = 0; i < 10; i++)
です。-
丸括弧の中の1番目の部分は、ループを開始する前に実行されます。通常では、ループ変数の初期値を設定します。
-
2番目の部分は、各ループの最初に評価されます。このエクスプレッションの評価がfalse(ゼロの値)の場合、ループから抜けます。
-
3番目の部分は、各ループの最後に実行され、通常ではループ変数の値を増分します。
-
-
ループの度に実行されるステートメントまたはブロック(
{}
)を記述します。 -
ループ内に
break
やcontinue
を使用することができます。
{ float out = 0; for (i = 0; i < 10; i++) { out += i; } return out; }
while
ループもC言語に似ています:
-
while
の後には、丸括弧(()
)を付けて、その中にエクスプレッションを記述し、その後に、ステートメントまたはブロック({}
)を記述します。各ループの最初に、そのエクスプレッションがtrue(ゼロ以外の値)に評価されると、以降のステートメント/ブロックが実行されます。 -
ループ内に
break
やcontinue
を使用することができます。
{ float k = ch("parm"); float i = 0; while (i < k) { i++; if (i % 2 == 0) continue; } return i; }
Tips ¶
-
HScriptエクスプレッションとローカル変数をパラメータに使用することで、ジオメトリノードのジオメトリを修正するのは簡単です。とはいえ、Point WrangleやAttribute WrangleなどのノードでVEXスニペットを使用してジオメトリを修正する方が非常に効率的です。
将来のバージョンのHoudiniは、ジオメトリを修正するのに、パラメータエクスプレッションよりもおそらくVEXの利用を推進していきます。
-
Window ▸ HScript Textport を選択して、以下をタイプすることでエクスプレッションの値をチェックすることができます:
echo `expression`
-
Houdiniは、ネットワークの“レシピ”を使って常に“ゼロから”各フレームを作成します。エクスプレッションは、前のフレームから ではなく 、ノードの初期セットアップから取得する値に対して常に作用します。
例えば、ランダムなオフセットをグリッド内の各ポイントのY位置に追加するPointジオメトリノードをセットアップします:
Position Y
@P.y + rand(@Frame * @ptnum)
…アニメーションを再生すると、それらのポイントは上下に滑らかに移動せずにランダムに飛び回ります。これは、各フレームでネットワークが平坦なグリッドから開始して、ランダムな移動量がそこに適用されるからです。 このエクスプレッションは、前のフレームのジオメトリに対して実行されません。
HScriptエクスプレッション内の引用符 ¶
Strings ¶
シングルクォート('
)内のテキストは展開されません。ダブルクォート("
)内のテキストは変数が展開されます。ダブルクォートで閉じた文字列は1つの引数として見なされます。
バックスラッシュ文字(\
)は、次の文字をエスケープします。例えば、文字列内にダブルクォートを使用するには以下のようにします:
"I had a \"great\" time."
文字列を変数展開したくない時は、シングルクォートを使えば評価を高速化することができます。
スペースなしで続けて引用文字列を2つ記述すれば、1個の引数として見なされます。この例では…
set foo = "Hello world" echo '$foo='"$foo" $foo=Hello world
…echoコマンドは1つの引数を持ちます: '$foo=Hello world'
.
埋め込み ¶
HScriptコマンド言語では、バッククォート(\
`)内のテキストがエクスプレッションとして評価されます。例:
echo `strlen("$foo")`
Tip
HScriptコマンド言語を使ったスクリプトは廃止予定です。代わりにPythonを使用してください。
文字列の解読では、以下の(非常に不自然な)例のようなネスト化した引用符は展開できません:
echo `system("echo `ls`")`
…しかし、これはバッククォート(場合によっては、続けて複数のバッククォートを使用)を上手く使って色々な評価レベルで引用符を保護して展開することができます:
echo `system('echo \`ls\`')`
HScriptグローバル変数 ¶
Tip
いくつかのグローバル変数には、VEXスニペットで利用可能な変数に一致する@
で始まる同等のものがあります。
プレイバック ¶
Note
$FF
(浮動小数点フレーム番号)の値に基づいてトランスフォームを計算する際に精度問題に遭遇することがあります。
例えば、30個のモーションセグメントがあった場合、各セグメントは0.00138888秒になります。
長尺アニメーションのフレーム1800番では、そのセグメント時間は75.00138888888のような数値になります。
これがパイプラインのどこかで単精度に切り捨てられた場合、75.0014のような数値に丸められて、ストロボ現象が発生します。
浮動小数点フレームの精度問題を修復するために、$FF
は精度調整された値を常に返します。
これは倍精度評価を台無しにしてしまいます。
精度問題を回避するには、代わりに$T
(単位が秒の浮動小数点時間)を使用すると良いでしょう。
$FF
を$T * $FPS + 1
に置換することで(または、Pythonでhou.frame(True)
を使用することで)ストロボ現象を修復することができます。
|
|
説明 |
---|---|---|
|
1秒あたりのフレーム単位での再生速度(プレイバーのコントロールで設定)。 |
|
|
アニメーションの最初のフレームとなるフレーム番号(プレイバーのコントロールで設定)。$NFRAMES(アニメーションのフレーム数) = $FEND - $FSTART + 1。 |
|
|
アニメーションの最後のフレームとなるフレーム番号(プレイバーのコントロールで設定)。 |
|
|
現行フレーム(プレイバーのコントロールで設定)。これは非常に便利な変数で、特にレンダリングした画像のファイル名のナンバリングでよく使います。 |
|
|
|
浮動小数点フレーム番号。小数点以下6桁に丸められます。
このセクションの上部に載せている |
|
Houdini20より前のバージョンの |
|
|
アニメーションのフレーム数。$NFRAMES = $FEND(アニメーションの最後のフレーム) - $FSTART(アニメーションの最初のフレーム) + 1。 |
|
|
プレイバーに表示する最初のフレームとなるフレーム番号。プレイバーはフレーム全体の一部だけを表示することができるので、長いアニメーションから特定の部分に集中することができます。$RFSTARTと$RFENDはプレイバーで表示する一部のフレーム範囲を設定します。 |
|
|
プレイバーに表示する最後のフレームとなるフレーム番号。 |
|
|
|
秒単位での現行時間。これは、($F-1)/$FPSと同等です。 |
|
秒単位でのアニメーションの全体の長さ。 |
|
|
秒単位でのアニメーションの開始時間。 |
|
|
秒単位でのアニメーションの終了時間。 |
一般 ¶
|
現行テイクの名前を含んでいます。 |
|
|
数学定数で、自然対数の底であるe(2.71828…)。 |
|
|
Houdiniのインストール場所。 |
|
|
|
|
|
現在のシーンファイルを含んだディレクトリ。 |
|
|
読み込まれたシーンファイルのファイル拡張子を含んだフルパス。 |
|
|
拡張子なしの現行シーンファイルの名前。これは、シーンの名前をベースに他のファイル名を構築するのに役に立ちます。 |
|
|
ホームディレクトリ。 |
|
|
||
|
数学定数のπ(3.1415926…)。 |
チャンネル ¶
|
Operator Stringの略で、現行オペレータの名前を含んでいます。 |
|
現行チャンネル名。 |
|
In Valueの略で、セグメントの開始での値。 |
|
Out Valueの略で、セグメントの終了での値。 |
|
In Slope。セグメントの開始での傾斜。 |
|
Out Slope。セグメントの終了での傾斜。 |
|
In Acceleration。セグメントの開始でのアクセラレーション。 |
|
Out Acceleration。セグメントの終了でのアクセラレーション。 |
|
ローカル時間(ストレッチまたはオフセットを含みません)。 |
|
セグメントの開始時間。 |
|
セグメントの終了時間。 |
|
セグメントのローカル開始時間。 |
|
セグメントのローカル終了時間。 |
|
前のセグメント開始時間。 |
|
次のセグメント終了時間。 |
COP ¶
|
現行COPの開始フレーム。 |
|
現行COPの終了フレーム。 |
|
現行COPのフレームの数。 |
|
1番目の入力COPから利用可能なフレームの数。 |
|
グローバルフレーム増分値を取得します。 |
|
現行の画像幅。 |
|
現行の画像高さ。 |
Renderノード ¶
|
レンダリングする現行フレーム。 |
|
レンダリングするフレームの数。 |
See also |