Houdini はじめてのBlock Begin/End

#誰向け？
Houdiniのいくつかチュートリアルを触り始め、少し自分でもノードを組んでみようかな？という方向けの記事です。
私がHoudiniを触り始めて最初にぶつかった壁が「Block Begin/End」の使い方です。

#Houdiniでの繰り返し
##どんなノードを使うの？
繰り返しに使うためのノードはBlock Begin/Endノードです。
ネットワークグラフのペインで、Tabキー→Forで検索すると何種類か出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/deff0e80-2006-0c58-db07-37f7aa4755e4.png)

これらはすべて、***パラメータ違いのBlock Begin/Endノードのセットです。***
（時々、Block Begin/End以外のノードもついてきます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/47d7f35a-7b2e-7e56-6c4d-e046c5ad548b.png)

繰り返したい処理を、このblockノードで挟みます。
繰り返し処理が行われる部分が、オレンジの枠で囲まれるようになります。

なぜ、こんなに何種類も分けられているのでしょうか？
それは、***「何に対して繰り返し処理を行うのか？」***がそれぞれ違うためです。

##Method
この、「何に対して」を決めるためのパラメータが以下の3つです。
1.Block BeginのMethodパラメータ
2.Block EndのIteration Methodパラメータ
Block EndのIteration Methodパラメータ

順番にみていきましょう。

##iteration
まず、「イテレーション」の意味を押さえておきます。
例えば、「箱から白い玉を取り出し、偶数回目なら赤、奇数回目なら青に塗る」という処理5回を行うとします。

この処理を、細かく手順分けすると以下のような書き方になります。

カッコ内の処理を5回行う{
　箱から玉を１つ取り出す
　もし今が偶数回なら
　　玉を赤く塗る
　偶数回でないなら
　　玉を青く塗る
}

このときの、「箱から玉を1つ取り出す」〜「玉を青く塗る」までの動作をひとまとまりと考えます。
これが、1つのイテレーションと考えます。

処理の中にある「今」とは、「今行っている処理が何回目のイテレーションか」ということを表します。

##Block BeginのMethod

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/6e5c7af3-d27c-6d33-b950-2fadd10b1d78.png)

Block BeginのMethodパラメータでは、
各イテレーションが始まる際に、どのような状態のジオメトリーを受け取るか？を設定します。

###Fetch Feedback
前のイテレーションで得た結果を受け取ります。

例えば、前のイテレーションで、箱にりんごを１こいれたとします。
Fetch Feedbackでは、1つのりんごが入った箱をそのまま受け取り、現在のイテレーションでりんごをもう1つ入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/58ef9725-31e3-0189-3e4a-9c256da281e0.png)

###Fetch Piece or Point
1つのピースまたは1つのポイントずつ、イテレーションの最初に受け取ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/3d3fee48-1b01-60fb-cb11-481fe42a0992.png)

ピースとは、ひとかたまりになったプリミティブです。
ユーザーがアトリビュートによって指定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/d064d1e3-d8a3-3d3a-eac0-9d34a954935e.png)


###Fetch Metadata
このBlock Beginノードを「メタデータ」として扱うために設定する値です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/99daa54a-69ce-4ffc-b43b-14b576217c70.png)

メタデータ用ノードのDetailアトリビュートには、「今現在のイテレーションは何回目か」を示す「iteration」アトリビュートなどが存在しています。
それぞれのイテレーションで違うことをしたいときに、detail()エクスプレッションを使ってこの値を読み込んで使用することができます。

###Fetch Input
常にインプットされたジオメトリーを各イテレーションの最初に受け取ります。

例えば、前のイテレーションで、箱にりんごを１こいれたとします。
Fetch Inputでは、最初の箱をそのまま受け取り、現在のイテレーションでりんごを1つ入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/46abe3b8-e4c8-c560-eb44-1a93addd35e5.png)

##Block EndのIteration Method

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/c2051bf0-9dcf-7adb-7857-7a9a66524340.png)

このパラメータではイテレーションの回数をどのように決めるかを設定します。

###Auto Detect from Inputs
入力されている情報から、イテレーション回数を検出します。
検出方法は以下の通りです。ヘルプから引用しました。

>2番目の入力が存在した場合、Piece Iterationメソッドがそのジオメトリに使用されます。
>同様に、Piece Block Pathが存在した場合、Piece IterationメソッドがPiece Blockの入力に使用されます。 
>どちらでもない場合、Countメソッドが使用されます。

###By Pieces or Points
ピースまたはポイントの数だけ処理を繰り返します。
例えば、ピースが12種類あるなら、12回処理を繰り返します。

###By Count
すぐ下にあるMax Iterationsパラメータに設定した回数分、処理を繰り返します。

##Block EndのGather Method

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/9f1f9e0c-d5db-8e50-3a1b-e7c228faa2fe.png)

ここでは、すべてのイテレーションの処理が終わったとき、その結果をどのように取得するかを設定します。

###Feedback Each Iteration
ループの最後のジオメトリを取得します。
Block BeginのMethodをFetch Feedbackにしていると、ちょうど処理を累積した結果を得ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/839f8f47-a8ec-c9cb-2b34-84367672a825.png)

###Merge Each Iteration
全てのイテレーションの結果を得ます。

Fetch piece or pointsのとき、ピースごとに処理を行っているので最後に結合してやる必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434798/58611897-1eb1-f460-09e9-9a51f74c5d68.png)

#まとめ
最初は混乱しやすいパラメータについてまとめてみました。
For Loopが使えるようになると、グッとHoudiniでできることが増えるのでためしてみてください。
コメントや指摘などあればぜひお願いいたします。