getAttrとskinweight

スキニングしたジオメトリのweightを保存しておこうと思い、MELを走らせる。
例えばこんな感じ。

getAttr( “skinCluster1.weightList[0].weights” );


これで配列の値が返って来る。

が、全部の骨の情報は返ってこない。
値が0より大きいものしか返ってこない。

全部の骨のweightを取得するには、結局スキニングに関係している骨の数で

for( i=0; i<jointNum; i++ )
  getAttr( “skinCluster1.weightList[0].weights[“+i+”]” );

と、してやらないといけない。
↑値をとるならしっかり配列に代入するのもお忘れなく。

つーかなんという仕様ですかこれは。

値が0の要素に対してgetAttrを行うと、そこの値は有効になるらしく、
次にgetAttrしたときは配列のサイズが1個増えてる。

なんということですか。

使いづらくて仕方ないよ、、

結局このスクリプトで一番遅いのは、全頂点でインフルエンスオブジェクトの数だけ
getAttrをする必要があるというところ。

例えば20個のジョイントで3000頂点のキャラだとすると、
3000×20で60000回のgetAttrをする必要が出てくる。
一回0.01秒だとしても600秒かかる。
実際にはもっと速いとは思うけど。

なんつーか、もっとまともな仕様にしてほしい。
問い合わせするたびに要素が増える配列とか滅茶苦茶な仕様はやめて下さい。。

それともおれがどこか間違ってるってことなのかなぁ、、、
誰かご存知だったら教えてください。。。

ちなみに、取得した情報は、某社様にならって、Pickleを使って保存してます。
cPickleが速いということでそっち使ってますが、非常に楽でいいな!
何個かの辞書と配列を要素として持った配列をdumpしてます。
一個のオブジェクトがデカくなりすぎるのはちょっと気になるけど、
結局fileをopenしてもどこかにデカいオブジェクトは存在するんだろうし、変わんないか。

現在、前に作ったやつを改良中なのですが、なんか読み込みが上手く行かなくなったwww
ぼちぼち直しますよ。

「getAttrとskinweight」への10件のフィードバック

  1. weightはスクリプトベースで、まともなスピードで出ますか?
    みんなスピード的につらくてplug-inExporterを作ってるように見えますが・・・。(なのでその例文はちょっと探せば2-3出てくる)

    Pythonベースだと早く出せるのかな。だとしたらいいな。

  2. >hajimeさん
    いやー、遅いです。遅すぎますww
    pickleを使ってオブジェクトのシリアライズが出来るのは非常に便利なのですが、getAttrがアホ過ぎるというところがネックになって非常に遅いです。
    やっぱりみんなplug-inですか、、、
    僕も練習がてらやってみようかな、、

  3. getAttrではなくskinPercentを使えば
    1頂点1コマンドでweight情報を取得できますよ

  4. >あきおさん
    その節はどうも。

    skinPercent!そんなコマンドが!!
    おおおおおお全然気づかなかった、、、
    ナイス情報ありがとうございます!

    早速スクリプトを修正してきまーす。

  5. そういや俺もskinPercent使ったや。
    でもゲームキャラ程度以上のポリゴン数では
    重すぎて使えなかったと思ったなぁ。

    修正されたのかな?

  6. >hajimeさん
    重いんでしょうか、、、
    今は1万ぐらいだからそこまで気にもなりませんが、100万200万だったら、激遅だと思います。
    僕は今importが遅いことに悩んでいます。
    skinPercent使っても配列突っ込めばOK!とかにはならないし。
    うーん。

    にしても今日はコメントがすごいな。。

  7. えーと、cPickleを使うツールはアレでアレしてごにょごにょなんですが
    skinPercent使う自作のツールも使っていて
    速度的には同じくらいです。
    MELだとこんなかんじです。

    for ( $vtx in `ls -sl -fl`){
    stirng $vals[] = `skinPercent -q -wi $skinCluster $vtx`;
    $expStr = $expStr+"skinPercent ";
    int $i=0;
    for($inf in `skinPercent -q -inf $skinCluster $vtx`){
    $expStr = $expStr + "-tv "+$inf+" "+$vals[$i++]+" ";
    }
    $expStr = $expStr+$skinCluster+" "+$vtx+";\n";
    }
    fprint $file $expStr;
    

    100万200万のものを素でOneSkinでバインドする事は
    今までしたことはないので
    速度的にどうなのかはちょっとわからないですね
    ただweightを吐き出す機会ってそんなに頻繁に発生するものでもないので
    極端な速度低下あるいはフリーズが起きない限りは
    気にしたことなかったです

  8. >あきおさん
    なるほど。なんとなく一緒な感じです。
    それよりも$i++の所に感心しました。なるほど、、とww
    あんまりそういうトリッキーな(トリッキーでも無いけど)使い方したことないので、僕もそういうのやりたいです 笑

    言われてみればweightの出し入れって数万ぐらいまでなもんですよね。
    1万ぐらいだとほとんど気になんない感じですよ、個人的には。

    cPickleのごにょごにょが気になりますww
    今度こっそり教えてください、、、

  9. 以前、僕も同じ問題で行き詰まった覚えがあります。
    その時は、自社内のエンジニアの方に質問したら、とっておきのコマンドを教えてくれました。

    listAttr -m -st “weightList[0].weights” “skinCluster1”;

    これを実行してみてください。
    多少は速度が上がる And 保存するデータ量が軽減されるはずです。

  10. すんません!
    投稿後にチェックしたら何も返ってきてませんでしたw

    print`listAttr -m -st “weights” “skinCluster1.weightList”`;

    こっちが正解です。

コメントを残す

メールアドレスが公開されることはありません。