2013/04/12

melからpymelへ書き換えてみる[その3]

なんか四月も半ばというのに雪が降ったりしたそうですね。。。
さて、
なかなかmelからPythonへの一歩を踏み出せないときのための「書き換えてみるシリーズ」の三つめです。
例によって、この記事で取り上げていた小つぶなスクリプトを書き換えていきたいと思います。

※ちなみにその1は コチラ  その2は コチラ


今回も(中略) import pymel.core as pm です

三つ目は「選択したものの位置と回転を別のものに揃えるスクリプト」でした。
まずは原型というかmel版↓

if (size(`ls -sl`) == 2){
    doCreateParentConstraintArgList 1 { "0","0","0","0","0","0","0","1","","0" };
    $pConsts = `parentConstraint -weight 1`;
    delete $pConsts[0];
    }

書き換えるにもいろいろなアプローチがあると思うんですが、最初は単純な書き換えということで、このコンストレインを使ってそろえる方法を踏襲してみたいと思います。

とりあえずコンストレイン


pm.parentConstraint()


これで当初のそろえるという目的は達成できました(笑
ただしコンストレインノードが出来てしまうので、削除しないといけませんね。

変数で受け取って

pCnst = pm.parentConstraint()

普通にデリート

pm.delete(pCnst)

これに、選択個数による判定を付けたり、フラグを指定したりすれば、当初に掲げたmelの再現は完成です。


if len(pm.selected()) == 2:
    pCnst = pm.parentConstraint()
    pm.delete(pCnst)


※ pm.parentConstraintの括弧のなかみは保留しました(笑

でもこれだとちょっと、コンストレインノードわざわざ作って消すというのが、
なんかヤですね。すっきりしません。

値をそろえるということで、
以下のような方法もとれます。


if len(pm.selected()) == 2:
    toObj = pm.selected()[0]
    fromObj = pm.selected()[1]
    toObj.t >> fromObj.t
    toObj.t // fromObj.t
    toObj.r >> fromObj.r
    toObj.r // fromObj.r


ちょっと行数がかさんでいますが
やっていることは先のコンストレイン作戦と一緒です。
PyMELでは、「>>」でアトリビュートのコネクト、「//」でコネクトのカットが行なえます!便利!
…便利か?
分かりませんが、てっとり早い感はあります。
でもこれだと、どっちかというと便利というよりは、出来るからやった、
やってみたかったからやった感が濃厚です。正直。
普通に値のやりとりになるのでグループ化されていたらちゃんと動かないですし、
それに、
コンストレインによる方法と同じく、何かを一旦つなぐというのは、
RIGの組み方によってはアウトでしょうから、
あまり健全なやりかたとは言えません。
(しかも、つないだあと用が済んだら切っちゃうわけですし)

というわけで、↓こんな方法もあります。
コンストレインも、アトリビュートのコネクトも不要で、グループ化されていても大丈夫です。


if len(pm.selected()) == 2:
    toObj = pm.selected()[0]
    fromObj = pm.selected()[1]
    fromObj.setMatrix(toObj.getMatrix(ws=1),ws=1)


選択個数の判定や変数への代入までは一緒ですから、
このスクリプトは実質最後の一行に集約されています。
setMatrix、getMatrixメソッドは、トランスフォーム(位置、回転、拡縮)の変換に使われる行列を直にやりとりするためのものです。マトリックスを取得すれば、これらの値を一括で扱うことができますので、今回の目的に適っています。

オプションで付けている「ws」は「WorldSpace」の略で、これを有効にすることで、グループ化されているかどうかに関わらず、ワールド空間での値を取得できます。
(きっと .getAttr('worldMatrix') と一緒ですね)

これで、コネクトもしなくて済みます。

ちなみに、Python度合いをゴリ押ししてワンライナーにすることも可能です。


if len(pm.selected()) == 2:pm.selected()[1].setMatrix(pm.selected()[0].getMatrix(ws=1),ws=1)

さすがにごちゃついてて、一体なんなんだ!?って感じがするので、
おすすめできませんが(笑
(ちなみに、条件判定とかじゃない場合に、複数行を一行にしたい場合、
行末にセミコロンをつけることで可能になります。melのpythonコマンド内でときどき使います。。。)


というわけで、今回はPyMELなコネクトと、
ワールドマトリクス云々について右往左往してみました。

最後に、今日のお題になったmelをもう一度。。。

if (size(`ls -sl`) == 2){
    doCreateParentConstraintArgList 1 { "0","0","0","0","0","0","0","1","","0" };
    $pConsts = `parentConstraint -weight 1`;
    delete $pConsts[0];
    }

いや、とくに意味はありません。

やっと三つ目が書けました。
当該記事の三つの小粒スクリプトはこれで書き換え終えたわけですが、
また小粒なネタをみつけては書き換えてみたいと思います。


0 件のコメント:

コメントを投稿