2014/07/20

【vol.3】「Mayaちゃんの作り方」Hairスクリプト



vol.3 に掲載予定の記事「3DCGメイキング Mayaちゃんの作り方 (by ナカムラさん)」に、Hairに関するスクリプトが登場するのですが、
誌面に載せるとコピペできないので、こちらでご紹介。

具体的には、
「選択した複数のfollicleshapeのoutHairアトリビュートをhairsystemshapeの inputHairアトリビュートにコネクトするスクリプト」
です!






このスクリプトでどんな課題が解決されるかというと……
Curve(follicle)に、複数の hairSystem をアサインする、という作業の自動化を図れます。
この作業を行なうことで、下図のような仕組みをローコストで作ることができ、
ヘアシステムを複数用いた、単純じゃない感じの毛束感の表現につながります。
ただ、これを行うためにはカーブのつなぎなおしが発生するのですが、
カーブ数が膨大になってくると、手作業ではとても現実的で無くなってきます。

そこで用意したのが今回のスクリプト。

▼コネクト用

# connect hair
import pymel.core as pm

hsysGrp = []
flclGrp = []
objs = pm.selected()

for obj in objs:
    if obj.nodeType() == 'transform':
        for child in obj.listRelatives():
            if child.nodeType() == 'hairSystem':
                hsysGrp.append(child)
            elif child.nodeType() == 'follicle':
                flclGrp.append(child)
    elif obj.nodeType() == 'hairSystem':
        hsysGrp.append(obj)
    elif obj.nodeType() == 'follicle':
        flclGrp.append(obj)

for flcl in flclGrp:
    for hsys in hsysGrp:
        cnctGrp = flcl.outHair.connections()
        if cnctGrp:
            connected =None
            for hs in cnctGrp:
                if hs.getShape().name() == hsys.name():
                    connected = True
            if connected:
                continue
        ihAttr = hsys.inputHair
        maxIndex = ihAttr.getArrayIndices()[-1]
        pm.connectAttr(flcl.outHair,hsys.inputHair[maxIndex+1],f=True)

▼コネクト解除

# disconnect hair
import pymel.core as pm

hsysGrp = []
flclGrp = []
objs = pm.selected()

for obj in objs:
    if obj.nodeType() == 'transform':
        for child in obj.listRelatives():
            if child.nodeType() == 'hairSystem':
                hsysGrp.append(child)
            elif child.nodeType() == 'follicle':
                flclGrp.append(child)
    elif obj.nodeType() == 'hairSystem':
        hsysGrp.append(obj)
    elif obj.nodeType() == 'follicle':
        flclGrp.append(obj)

for flcl in flclGrp:
    oh = flcl.outHair
    for hsys in hsysGrp:
        cnctSet = oh.connections(c=True,s=True,p=True)
        [oh.disconnect(connection[1]) for connection in cnctSet if connection[1].node() == hsys]

……というスクリプトが、冒頭のHairの感じを出すのに使われました。
それぞれ、任意の follicle 繋ぎたい hairSystem を選択して実行してみてください。

あと編集作業は下図のように順次進行中です!(唐突

どうぞお楽しみに!

vo.3 特設ページできました - こちら

〜〜〜〜〜〜〜〜〜


以下、スクリプトの解説です。

コネクト用】
大きく二つのforブロックから成っています。
前半のforブロックでは、pm.selected() で得たノードたちが hairSystemなのかfollicleなのかを仕分けしています。この仕分けブロックは、コネクト解除用でも使っています。
ビューポート上での選択と言うか、トランスフォームノードを選択したときにシェイプを見るのと、ノードエディタなどで該当する種類のノードを直に掴んだ場合との両方に対応するためになんやかんやしています。
もっといいやり方があるんじゃないかと思います(そして書いた内容を既に忘れつつあります(汗))

後半のforブロックで、follicleごとにhairSystemをつないでゆきます。
まず、当該follicleのoutHairアトリビュートになにかつながっていたら、いまからつなごうとしているhairSystemと既につながってるんじゃないか、どうなのか、確認します。
そのあと、hairSystem のinputHairアトリビュートのインデックスを取得し、
それより一つ大きなインデックスナンバーを指定してfollicleをつないでいます。
(しかし、たしか「インデックスいっこ増やしてつなぐ」コマンドがあった気がします。わらい。)


コネクト解除用】
前半のforブロックは同じなので割愛。
後半、当該follicleのoutHairアトリビュートを取得しておいて、hairSystemごとにdisconnectメソッドでブッチブッチ切って行きます。生意気にもlist内包表記を使っていますね。ええ、覚えたてで使ってみたかったのです。未だ慣れていません。



■参考

ナカムラさん( twitter : @Tsubasa_7 )
https://twitter.com/Tsubasa_7

pymel.core.general.listRelatives
http://download.autodesk.com/global/docs/maya2014/zh_cn/PyMel/generated/functions/pymel.core.general/pymel.core.general.listRelatives.html

follicle Node - outHairアトリビュート
http://help.autodesk.com/cloudhelp/2015/ENU/Maya-Tech-Docs/Nodes/follicle.html#attroutHair

pymel.core.general.PyNode - connections()
http://download.autodesk.com/global/docs/maya2014/ja_JP/PyMel/generated/classes/pymel.core.general/pymel.core.general.PyNode.html#pymel.core.general.PyNode.connections

hairSystem Node - inputHairアトリビュート
http://help.autodesk.com/cloudhelp/2015/ENU/Maya-Tech-Docs/Nodes/hairSystem.html#attrinputHair

pymel.core.general.Attribute - getArrayIndices()
http://download.autodesk.com/global/docs/maya2014/ja_JP/PyMel/generated/classes/pymel.core.general/pymel.core.general.Attribute.html?highlight=getarrayindices#pymel.core.general.Attribute.getArrayIndices

pymel.core.general.connectAttr
http://download.autodesk.com/global/docs/maya2014/ja_JP/PyMel/generated/functions/pymel.core.general/pymel.core.general.connectAttr.html?highlight=connectattr#pymel.core.general.connectAttr


pymel.core.general.Attribute - disconnect()
http://download.autodesk.com/global/docs/maya2014/ja_JP/PyMel/generated/classes/pymel.core.general/pymel.core.general.Attribute.html?highlight=disconnect#pymel.core.general.Attribute.disconnect

0 件のコメント:

コメントを投稿