ノードっていくつあるんですか？

Houdini アドベントカレンダー2016 19日目の記事です。

内容は掲題の通りですので……
この時点で「あー、ﾊｲﾊｲ」という方はそっ閉じしていただいたり、
他にもっといい方法知ってたらこっそり教えていただけたりすると嬉しいです。

# NodeTypeという当て推量

houモジュールの中を見てみようかなーと思います。
dirで返ってくるリストのうち、「NodeType」が含まれていればそれっぽいような気がするので、
そのように調べてみます。

```python
for i in dir(hou):
    if 'NodeType' in i:
        print( i )
```

すると

<img width="480" alt="NodeType" src="https://qiita-image-store.s3.amazonaws.com/0/102581/273a048e-70c4-d861-f126-35a573ebc51f.png">

結構返ってきました。
前半のとか、_swigregisterとかは違いそうです。
「NodeType」と「NodeTypeCategory」がいるのが興味深いですね。
後者の方がよりそれっぽい気がします。

# inspect.getmembers

今度は、inspectモジュールのgetmembersを使って見てみます。

```python
import inspect
for i in inspect.getmembers(hou):
    if 'NodeType' in i[0]:
        print i
```


<img width="592" alt="getmembers" src="https://qiita-image-store.s3.amazonaws.com/0/102581/58c2cce1-8d00-05f6-7933-7b942dc287e4.png">

NodeTypeCategory系は、軒並み **built-in function** なようです。
これらの関数は、「NodeTypeCategory」型を返してくれます。

```python
type( hou.sopNodeTypeCategory() )
<class 'hou.NodeTypeCategory'>
```

# NodeTypeCategory

NodeTypeCategory型で、とりあえず名前（name）でも見ようかなと n をタイプしたら、ついでに「nodeTypes」というのもサジェストされました。
<img width="216" alt="name_nodeTypes" src="https://qiita-image-store.s3.amazonaws.com/0/102581/4cc5ed35-d596-5209-c0a4-794ed7652e1c.png">

```python
sopCategory.name()
'Sop'

sopCategory.nodeTypes()
```

nameの方は想像通りの結果ですが、
ついでに見つけたnodeTypesの方はこういう感じになりました！
<img width="1057" alt="nodeTypes" src="https://qiita-image-store.s3.amazonaws.com/0/102581/72784149-b9cd-5afc-29d0-d3c610d6f774.png">

ちょっとギョッとしましたが、これで各ノードカテゴリ内のノードをチェックできそうです。

# nodeTypesの中身をカウント

```python
import inspect
for i in inspect.getmembers(hou):
    if 'NodeType' in i[0]:
        if inspect.isbuiltin(i[1]):
            try:
                nodetypecategory= i[1]()
            except:
                continue
            nts = nodetypecategory.nodeTypes()
            print( nodetypecategory.name(),len( nts ) )
```

途中のtry-exceptは、swigregisterの人たちがエラーを起こすために設けたものです。
下から2行目で先ほどのnodeTypesの結果である辞書を受け取り、カテゴリ名と共にその辞書の長さをプリントしてみました。

<img width="625" alt="count" src="https://qiita-image-store.s3.amazonaws.com/0/102581/1c3776fd-3aab-3bec-4603-c2e923c8ea37.png">

結果……
〜〜Net系はそれぞれ1ノードしかないのはわかるんですが、
SOPとかDOPとかVOPとかそんなに多いものなんですか？？？　そうですか。

一応結果を貼っておきます。H15.5.632です。

```
('ChopNet', 1)
('Chop', 103)
('CopNet', 1)
('Cop2', 145)
('Dop', 435)
('Object', 146)
('Particle', 1)
('Pop', 68)
('Driver', 42)
('Shop', 205)
('Sop', 430)
('VopNet', 18)
('Vop', 816)
```

# nodeTypesの中身をカウント(特にCHOP）

比較的数えやすそうな**CHOP**を比べてみることにしました。
スクリプトの結果が上記のように「103」。

```python
chopNodes = hou.chopNodeTypeCategory().nodeTypes()
sorted( chopNodes.keys() )
```

<img width="1053" alt="スクリーンショット 2016-12-19 23.22.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/102581/5b17e526-5fe5-da25-f097-56bedfc7e6ef.png">

Houdini UI上だと……

<img width="577" alt="CHOP" src="https://qiita-image-store.s3.amazonaws.com/0/102581/88ba66dc-f994-4cc6-92da-bc9a97f2c622.png">

4列、25行。**掛け算くらいできます**
「`for`」と「`popnet`」と「`vopchoptype`」の3ノードが、UI上では見当たりません。

でも、H12時点のオンラインドキュメントを見てみると、`for`CHOPはありますので、
http://sidefx.jp/doc/nodes/chop/for.html
これらは、過去のシーンデータとの互換性を保つためとかで残してあるものなのだろうなと推察できます。
VOPがすごい量になってるのもそうアレなのでしょうか。

ではスクリプトでそのノードだけフィルタリングするには？
といったあたりは次回の宿題になりそうです。

# まとめ

サジェストに助けられました。
便利！！

次は [yone80@github](http://qiita.com/yone80@github) さんの「四角ポリゴンに合わせて変形」です。