2008年10月7日火曜日

blender - python 同じAction一掃(2)

…遥か昔

blender - python 同じAction一掃
http://blendermoe.blogspot.com/2007/11/blender-python-action.html


というのをやったんですが、これには重大なミスがありまして、
2つ続けて同じ値があった場合、消していたんですが、よく考えたら3つ連続したときに真ん中のを消さないと、バグってしまうんですよね。

これまた、遥か昔に気づいていたんですが、そのころはリアルタイムレンダリングしていなかったので、別に一掃する必要ないじゃんということで、放っておきました。


さて、リアルタイムレンダに移行して、データ量も考えないといけなくなったので、再び手を加えることにしました。ついでに、NLA上にある全てのActionに対して適用するように変更しました。

はい、こちら


import Blender
from Blender import *
from Blender.Armature import *

# ----------------------------------
# delete same IpoCurves
#
# return list of deleted for print
# [[ipo,curve,index], [ipo,curve,index] ...]
#
# ipos : list of Ipos
# frameNums : list of frame numbers
# ----------------------------------
def deleteSameCurve(ipos, frameNums):
deleted = []
for ipo in ipos:
if (ipo == None):
continue
for curve in ipo:
pre = None
prepre = None
index = 0
for time in frameNums:
# nothing
if (len(curve.bezierPoints) == 0):
continue
# not existed bezierPoint at time
if ([x for x in curve.bezierPoints if x.pt[0] == time] == []):
continue

value = curve[time]
# there are 3 same points, delete second
if (pre != None and prepre != None and
pre == value and prepre == value):
length = len(curve.bezierPoints)
curve.delBezier(index - 1 - length)
deleted.append([ipo, curve, index - 1])
else:
prepre = pre
pre = value
index += 1

return deleted

# ----------------------------------
# delete same IpoCurves from Armatures
# see: deleteSameCurve(ipos, framNums)
#
# return list of deleted for print
# [[[arm1's deleted elements], [arm2's], ... ]]
#
# ----------------------------------
def deleteSameAction():
deleted = []
frames = []
for act in NLA.GetActions().itervalues():
ipos = act.getAllChannelIpos().values()
frames = act.getFrameNumbers()
deleted.append(deleteSameCurve(ipos, frames))
return deleted

# ----------------------------------
# execute
# ----------------------------------

#printing is slow.. debug only
#print deleteSameAction()

print "start!"
deleteSameAction()
print "finish!!!"



結果







というわけで、成功してますが、データに関する非常に危険なスクリプトなので、必ずバックアップを取ってから実行してください。うまく行く保障は全くありません。
Blenderのテキストエディタで開いて、Alt-Pで実行後、コンソールにfinish!!!と表示されたら成功です。(割と時間かかります)


さて、うまく行ったものの、実はこのままではリアルタイム用途には使えないのです。IKを使用しているので、IKが関連するボーンにキーを打ち直さないといけません。

というわけで、続く!

0 件のコメント: