Houdiniで始めるPython

**Houdini Advent Calendar 2019 6日目の記事です。**


本投稿は私がプログラミングを勉強し始めたときに直面した

* 参考書は読んだけど、どうしたらいいのか分からない
* 環境構築が難しすぎて作る前から心が折れそう

という苦い経験を元に書かれています。
当時の私と同じ状況にいる方や、HoudiniでPythonを勉強したいけど何処から手を付けていいか分からない方の助けになれば幸いです。

※ Houdini、Python共に独学なので私の理解が間違っている部分があるかもしれません。
　そういった場合はご指摘下さると嬉しいです！



##目標
HoudiniとPythonを使った簡単なスクリプト作成の一連の流れが把握できる

##作るもの
選択しているノードの

**1. 名前の先頭にOUT_を追記する**
**2. 色を黒色にする**

![01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/244aeb88-cddc-0321-6035-e32ac39764c4.gif)


##スクリプト作成の流れ

1. シェルフツールを作る
2. やることを整理する
3. ググってみる
4. ヘルプページを眺める
5. 本制作
6. 完成


##1. シェルフツールを作る

まずは、これから作るスクリプトを登録する場所を用意します。
[※ シェルフのカスタマイズに関する詳しい説明はこちら](https://www.sidefx.com/ja/docs/houdini/shelf/customize.html)

1. シェルフの+をクリックして、 New Shelf...を実行してください
2. Name は「my_shelf」、 Label は「My Shelf」として下さい（別の名前でも構いません）
3. Acceptを押すとシェルフセットが作成されます
4. 新しく作ったシェルフ上で右クリックして、New Tool...を実行してください
5. Name は「out_prefix」、 Label は「OUT Prefix」として下さい
6. Acceptを押すとシェルフツールが作成されます


![02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/5ceb05d2-466a-78bd-67f7-b72e43991ac2.gif)


これで簡単にスクリプトを実行できるようになりました！


##2. やることを整理する


>選択しているノードの

>1. 名前の先頭にOUT_を追記する
>2. 色を黒色にする



これらを実現するのに必要な手順を整理してみましょう。
(とりあえずググってみるのもありです)
<br>
選択しているノード
**→ 選択しているノードが何なのか調べる**

名前の先頭にOUT_を追記する
**→ ノード名を調べる**
**→ OUT_をくっ付けた新しい名前を決める**
**→ ノード名を差し替える**

色を黒色にする
<b>→ 色を決定する(黒)</b>
<b>→ ノードに色を割り当てる</b>
<br>
必要な手順の洗い出しですが、初めは結構難しいと思います。
数をこなしていく内に慣れますので、そんなに心配しなくても大丈夫です。


##3. ググってみる

自分がしたいと思っている事を先人が既にやっていたり、ヒントになりそうなことを書いてくれていることが多々あります。そういった情報を見逃さないためにもググってみましょう。![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/197d6511-cbab-1775-d43f-8c85c3f055aa.png)


諸事情により検索画面はカットしますが、検索例と便利なテクニックを載せておきます。



**検索例**
* Houdini Python　選択したノード
* Houdini Python Selected Node 


検索する際は日本語だけでなく英単語を混ぜると求めている情報が見つかりやすかったりします。
<br>
**便利テクニック**

* ページ内検索
Ctrl + Fを押すと「ページ内検索」が出来るようになります。
画面下部に表示される検索窓にワードを入力すると、ページ内でそのワードがハイライトされます。
![04.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/95ef2058-6c9f-d653-2de1-d66459d9af03.gif)


* 完全一致検索
Googleなどで検索した際、検索ワードの含まれていないページが引っかかることがあると思います。
そういった場合は、検索したいワードを "" で括るとそのワードを含んだページのみが引っかかるようになります。
<br>
これらを使えるようになると調べ物をするときの効率がグーンとアップしますので是非覚えてください。
普段のネットサーフィンも捗ること間違いなしです。
[※ その他のGoogle検索テクニックはこちらです](https://support.google.com/websearch/answer/2466433)


##4. ヘルプページを眺める

ググっても情報が見つからない時や、見つけた情報がよく分からない時はヘルプページを眺めてみましょう。
何か発見があるかもしれません。

英語
http://www.sidefx.com/docs/houdini/hom/hou/index.html
日本語
http://www.sidefx.com/ja/docs/houdini/hom/hou/index.html

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/320c69fa-5bc3-fd06-8ed6-502a8476afd5.png)


hou.***がずらーっと並んでますね。
houとはPythonを使ってHoudiniにアクセスするためのモジュールです。
（分からなくても、今はhouを使うとHoudiniで何かできるんだなぁぐらいの認識で大丈夫です）


これを見たときに「えー、全部覚えなきゃ駄目じゃーん」と思われるかもしれませんが、実はそうでもありません。ここで大事なのは、それっぽい検索ワードです。
例えば「選択しているノードが何か」知りたいとします。その際、上記で紹介したページ内検索を使って「Selected」と調べてみると、
>hou.selectedNodes() Return a list of all selected nodes.
>選択したノードすべてのリストを返します。

というのが見つかりました。
![07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/4300c350-cf64-ae9b-8fdc-32a3a2535ee0.gif)

更に、このページを開いて読んでみると

>Returns a sequence of hou.Node objects representing the nodes that are currently selected.
>現在選択されているノードを表現したhou.Nodeオブジェクトのシーケンスを返します。

と書かれた一文があります。

hou.Nodeは何ができるのか分からないので、リンクをクリックして調べてみると、

>name() → str 
>　Return this node’s name. 
>　このノードの名前を返します。 

>setName(name, unique_name=False) 
>　Set the name of this node
>　このノードの名前を設定します

>setColor(color) 
>　Sets the color of this item’s tile in the network editor to the given hou.Color. 
>　指定したhou.Colorで、ネットワークエディタ内のこのアイテムのタイルのカラーを設定します。 

といった情報が得られました。

※ ヘルプページあるあるなのですが、文章中によくわからない表現が結構あります。
　 最初はイラッとするかもしれませんが、これも慣れますのであまり気にしないようにして下さい。
　~~（特にMayaぁぁ!!）~~



##5.本制作

情報が揃ったら、それを元にスクリプトを書いてみましょう。
コメントを書いておきましたので、Pythonが分からない方でもなんとなく理解できると思います。

```python

# 選択中のノードを調べる（複数選択の場合もある）
sel_nodes = hou.selectedNodes()

# 順番に実行
for sel_node in sel_nodes:
    # ノード名を調べる
    name = sel_node.name()
    # 新しい名前を決める
    new_name = "OUT_" + name
    # ノード名を差し替える
    sel_node.setName(new_name)
    
    # 色を決める(黒)
    new_color = hou.Color((0,0,0))
    # 色を割り当てる
    sel_node.setColor(new_color)
```
<br>

**スクリプトを書く方法**

1. 最初に作ったシェルフツールを右クリックして、Edit Tool...を実行して下さい
2. Edit tool ウィンドウが表示されますので、Scriptタブを開いて下さい
3. Applyを押すと変更が保存され、Acceptを押すと変更の保存＋ウィンドウが閉じられます
![08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/88db16a9-c2e3-c1a7-540b-0bcfef8ebd2c.gif)


##6.完成
作ったスクリプトが正しく動作しているかチェックしてみましょう。
もし上手く行かない場合は、どこか間違っていますのでもう一度見直してみて下さい。


##追加課題

スクリプトは完成しましたが、本当にこれでいいのでしょうか？
実はこのスクリプトを同じノードに対して何回も実行するとノード名がOUT_OUT_OUT_....となってしまいます。
作るものとしては間違っていないのですが、使いづらいですよね。
![06.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526231/2fe062dc-87c3-979d-0b2a-4bf95668e3d0.gif)


ここで追加課題です。
**このスクリプトを同じノードに何回実行してもOUT_が増えないように改良してみてください。**


※ Pythonを全く知らない方は、今後Pythonを勉強する際に追加課題のことを頭の片隅に置きながら、勉強してみてください。そして、ひらめいたら是非改良してみてください。
<br>
ヒント（追加手順）
　1. 新しい名前を決める前に、名前の先頭にOUT_が付いているか調べる
　2. 付いていた場合は名前を変更しないようにする



##おわり
如何でしたでしょうか？
スクリプトの構想から作成まで、一連の流れを感じ取っていただけたのであれば幸いです。


ここまで読んでいただきありがとうございました！