2007年07月27日

頂点マップの切り取りについて modo 203

アイテムのポーズ云々をいろいろ作って、ちょっとしたボックスで人型のものを作ると、ちょっと楽しくなってきて、いろいろポーズをとらせるうちに動かしてみようとか思い出して、昨日一日根を詰めて作ったのがこれ。

dance.mpg

某作品の有名なダンスの頭の部分だ。怒られそうなのでこれ以上は書かないけど、はやくmodoでもアニメ付けたいな。modoでモデリングしてLightWaveでボーンを入れてMotionBuilderで動きを付けてLightWaveでレンダリングしてAfterEffectsでコンポジットした。MotionBuilderはいいねぇ。自分はStandard版なので7で打ち止めになっちゃったけど・・・orz モーキャプやらん身には50万円はちょっとねぇ。パテント関係がどうなっているか知らないけど、modoのアニメ機能もお手軽にキャラクタを動かせるようなのが付いてくれるといいなぁ。

ところで自分はWindows版のmodoを使ってるんだけど、頂点マップの切り取りをするとmodoが落ちる。201ではちゃんと動くんだけど、202、203では同じ症状が出るようだ。複数のパソコンで試したけど同じ結果になったので、バグの可能性もあると思うのだが他にそんな症状になってる人はいない?新規シーンで球をひとつ作ってウェイトマップをひとつ作ってポイントをいくつか選択してウェイトツールでポイントにウェイトマップを設定して頂点マップメニューから切り取りを選んで値を適当に0.5とかにしてOKを押すと「問題が発生したためmodoを終了します」でおしまい。ちなみに頂点マップの切り取りは閾値未満の値のウェイトマップを消去するツールで、不要なノイズ成分を消してウェイトマップをクリーンにするのに有効だ。仕方が無いので自分で機能劣化版を作ってみた。もし同じ状況になってる人がいたら使ってみてね。

プログラムは以下の通りだ。まずはリクエスタパネルを出して閾値を読み込み変数limitに入れる。

limit=panel("ClearMapsByThreshold.limit","1.0","percent","Limit",None)

次にプログレッシブバーが出せるように新規にモニターを1つ作って変数monにセットする。

mon=lx.Monitor()

mainレイヤのインデックスを取得して、選択モードをポイント選択モードにする。

main=lx.eval("query layerservice layer.index ? main")
lx.eval("select.type vertex")

選択されているポイントのタプルを取得して変数vertsにセットする。この時ポイントがひとつも選択されていなければ全選択扱いとして全てのポイントのタプルを取得して変数vertsにセットする。最後に選択状態を復元する時に無選択状態だったか調べられるように、無選択だった時には変数selectedにFalseを、選択ポイントがあった場合はTrueを代入しておく。

verts=lx.evalN("query layerservice verts ? selected")
if len(verts)==0:
    verts=lx.evalN("query layerservice verts ? all")
    selected=False
else:
    selected=True

シーン内のウェイトマップ全てのインデックスをタプルで取得し、変数weightにセットする。

weight=lx.evalN("query layerservice vmaps ? weight")

ポイント選択を解除して、処理対象のポイント数をモニターにセットしてプログレッシブバーの100%の値を設定する。

lx.eval("select.drop vertex")
mon.init(len(verts))

for文でポイントのインデックス全てを1つずつ取り出して変数vに代入してループする。ループする内容は、モニターのカウントを1つ進めてプログレッシブバーの目盛をひとつ増やし、ポイントを1つ選択して全ウェイトマップの値をひとつずつ調べてlimit未満の場合はマップをクリアーする。これを書いてて思ったけど、ウェイトのループとポイントのループは逆の方が効率いいな。でもその場合はモニターのパラメータを調整しないとね。ポイントのウェイトマップ値をクエリーするにはその前に該当するウェイトマップに対して何らかのクエリーを実行して対象となるマップを指定しておく必要がある。そして、マップをクリアするにはクリアするマップを選択する必要がある。この2つをlx.eval'select.vertexMap "%s" wght replace'  % lx.eval("query layerservice vmap.name ? %s" % w))のところでいっぺんにやってるよ。ウェイトマップを選択するselect.vertexMapコマンドはマップ名を指定して切り替えるので、クエリを使ってマップのインデックス番号からウェイトマップの名前を取得するクエリを発行している。これで選択マップも切り替えられるし、マップに対してクエリをしているからクエリの対象となるマップも指定できちゃうわけだ。

for v in verts:
    mon.step(1)
    lx.command("select.element",layer=main,type="vertex",mode="set",index=int(v))
    for w in weight:
        lx.eval'select.vertexMap "%s" wght replace'
         % lx.eval("query layerservice vmap.name ? %s" % w))
        if lx.eval("query layerservice vert.vmapValue ? %s" % v)<limit:
            lx.eval("vertMap.clear wght")

最後にポイントの選択状態を復元する。

if selected:
    for v in verts:
        lx.command("select.element",layer=main,type="vertex",mode="add",index=int(v))
else:
    lx.eval("select.drop vertex")

使い方はスクリプトを起動して閾値を入力するだけ。閾値未満のマップはポイントから消去される。でもこの未満が微妙なんだな・・・。

今回のスクリプトはもしかして役に立つのは自分だけかも・・・(汗)

それではまた次回。

スクリプトまとめページ( Down Load はこちらから)  

カテゴリー別ページ

modo操作メモ



take_z_ultima at 12:26│Comments(6)TrackBack(0)modo | CG

トラックバックURL

この記事へのコメント

1. Posted by Puff   2007年07月27日 13:02
「頂点マップメニューから切り取り」をやってみましたが、問題ありませんでした。IntelMACでOSX10.4.9です。ボックスの人形でも動いてくれると親しみが湧きますね。
2. Posted by take_z   2007年07月27日 13:29
インテルマックでは大丈夫でしたか。まあ301までの短い?間の辛抱ですね。
3. Posted by Puff   2007年07月27日 20:26
LightWaveが話しに良く登場するので、ウェブを探して見てみました。HyperVoxels、ボリュームライトなどはすぐにでも使ってみたい機能でした。
4. Posted by take_z   2007年07月27日 21:06
modoとLightWaveは兄弟みたいなもんですから、LightWaveのモデラーを使っても違和感を感じないと思いますよ。ボリューム系は確かに欲しいですね。
ボリュームライトは円錐とかで似たような事は出来ると思います。
明日のお題はそれで行きますか。
5. Posted by colm   2007年07月28日 02:16
はじめまして。いつも参考にさせていただいてます。
切り取りで落ちる不具合はウチの環境でも再現できました。
環境はWinXP@Ath64X2。Windows特有の問題ですかね。
6. Posted by take_z   2007年07月28日 11:46
colmさん、はじめまして。
自分ひとりじゃないなら何らかの不具合と考えてもいいでしょうね。今のところmodo単体で使う場合、ウェイトマップはそれほど重要なもんじゃないからあんまり問題にならないのかも知れないですね。しかしmodoはマックユーザーの率が高いですね。メモリーの事を考えるとあっちの方がいいのかも知れないですね。64ビット版のWinはまだアレですしね。

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 

Archives