初めての投稿というのもありちょっとした内容に触れてみたいと思います。
実際はもっと良い方法もあるかもしれません、その場合はぜひ情報を頂けると感激します。
# はじめに
今回は constraint されている、または connection されているアトリビュートを検知したいと思います。
なぜこの話題でこの内容かといいますと、listAttr を使用してアトリビュート情報を持ってきたとします。
ですがこれに isConnection をかけて調べても constraint や Expression は検知できますが
connection でつなげられている場合は素通りしちゃうんですね。
そのうえで connection されている attrbute を普通にコンストレインしてしまったとします。
アニメーションを焼き付けて戻す時には当然 connection は外れてしまうのです。
これは困る。
マジで困る。
リグの質が変わる可能性がある。(たまに外部の人がそれでリグを破壊することがあります。)
ということで何となくでコンストレインしたり、スクリプトでまとめて処理する時などにちゃんと検知して
もし connection されているようだったら対象から除外して欲しい!という意図をもってこの内容と致しました。
いっそチェッカー仕様にして warning しても良いでしょうね。
ということで本編に入ります。
# 実際にやってみる
connection = pm.listConnections(node, connections=True)※1
if connection:
for _c in connection:
if (not isinstance(_c[0], pm.general.Attribute)※2
or isinstance(_c[1], pm.nodetypes.AnimCurveTA)
or not _c[0].isDestination()):
continue
# 上記条件をすり抜けるアトリビュートは従属されているアトリビュート
はい、唐突にスクリプトをペッと貼り付けました、とりあえず上の二行(※1)はどうでも良いでしょう。
nodeにある全てのコネクションの取得と、取得できたかを見ているだけです。
listAttr からはアトリビュート属性のみを収集しますが、listConnections は非常に強力です。
本当につながっていれば何でも取ってきます、とりあえずここから洗い出しましょう。
まず listConnection でとった情報には当然一定の規則があります。
([nt.Attribute(name), nt.contraint(name)], [hoge, hage]...etc)
こんな感じです、内容は適当に書いたので細かいところは気にしないでください。
for文で回すと中のリスト部分が取れます。
ここの部分ですね:
[nt.Attribute(name)※A, nt.contraint(name)※B]
このリストの中は
※Aと書かれている側が必ずConnection関係を調べたノード側
※Bがそのコネクション内容(コネクション先)
となります。
さてここまで情報を抜き出したのであれば後は状態を確認するだけです。
今回の条件は for の中にある if に記載される条件式(※2)です。
if (not isinstance(_c[0], pm.general.Attribute)
or isinstance(_c[1], pm.nodetypes.AnimCurveTA)
or not _c[0].isDestination()):
行っていることを説明すると
- isinstance で、ノード側の情報がアトリビュートか調べる。
- アトリビュートが AnimCurve か調べる。(キーアニメーションしている場合は接続されているため)
- 最後にisDestination()、アトリビュート属性でかつ、従属先があるか調べる。
やや力技ですが、以上となります。
最後に
内容自体は非常に簡単ですので、皆様なにがしかの形で似たようなことを行っているかとは思います。
ただ他社様のデータに対し破壊的な処理を行う場合には、
改めて間に似たような処理を一度かませてくださると非常にありがたいです。
この調べ方は他にもいろいろできますので
今回はコンストレイン、コネクションとリグに使われるものを例にしましたが、
テクスチャ周りなどでも似たようなことはあるかと思います。
ある程度の経験者であればちゃんと調べて問題ない形にしていただいているかと思いますが、
もしスクリプト勉強し始めたばかりです!
ということであればできる限り丁寧に扱っていただきたいと思います。
何かあればご一報くださいませ。