実は、私の作成しているキャラクターのリグのファイルでは、Armatureの複製の処理でなぜかエラーが起こるので、このスクリプトの作者の方がBrender Artist Forumに投稿された古いバージョンとかを参考にして、スクリプトを改造したものを使っていました。
久しぶりにオリジナルのスクリプトを動かしてみたので、いろいろ混乱してしまいました。
何度もコメントをしてしまい、すみません。
ここから
########################################################
# prior to running script, make a duplicate of a reference (constrained) armature and remove constraints from the clone.
# simplistic example where ref and clone have to be identical with respect to bone names and order
# select the unconstrained armature clone, then shift-select the reference armature object.
# the actual motion of the reference armature's bones will be keyed in the clone's pose ipo
import Blender
from Blender import *
from Blender.Mathutils import *
import struct
import string
import bpy
import BPyMessages
import BPyArmature
from BPyArmature import getBakedPoseData
#=================
# Global Variables
#=================
# set senstitivity for displaying debug/console messages. 0=none, 100=max
# then call debug(num,string) to conditionally display status/info in console window
MODE=Blender.Get('rt') #execution mode: 0=run normal, 1=make test armature
DEBUG=Blender.Get('rt') #how much detail on internal processing for user to see. range 0-100
BATCH=False #called from command line? is someone there? Would you like some cake?
#there are two coordinate systems, the real, or absolute 3D space,
# and the local relative to a parent.
COORDINATE_SYSTEMS = ['local','real']
COORD_LOCAL = 0
COORD_REAL = 1
# User Settings - Change these options manually or via GUI (future TODO)
usrCoord = COORD_REAL # what the user wants
usrParent = False # True=clone keeps original parent, False = clone's parent is the clone of the original parent (if cloned)
usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin
# delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant
usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz
usrACTION = True # Offset baked Action frames to start at frame 1
CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on
ARMATURE = 'Armature' #en anglais
BONE_SPACES = ['ARMATURESPACE','BONESPACE']
# 'ARMATURESPACE' - this matrix of the bone in relation to the armature
# 'BONESPACE' - the matrix of the bone in relation to itself
#Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name
#bakedArmName = "b." #used for both the armature class and object instance
usrObjectNamePrefix= ""
#ipoBoneNamePrefix = ""
# for example, if on entry an armature named Man was selected, and the object prefix was "a."
# on exit an armature and an IPO curve named a.Man exists for the object as a whole
# if that armature had bones (spine, neck, arm) and the bone prefix was "a."
# the bones and IPO curves will be (a.spine, a.neck, a.arm)
R2D = 18/3.1415 # radian to grad
BLENDER_VERSION = Blender.Get('version')
# Gets the current scene, there can be many scenes in 1 blend file.
scn = Blender.Scene.GetCurrent()
#=================
# Methods
#=================
########################################
def debug(num,msg): #use log4j or just console here.
if DEBUG >= num:
if BATCH == False:
print 'debug: '[:num/10+7]+msg
#TODO: else write out to file (runs faster if it doesnt have to display details)
return
########################################
def getRenderInfo():
context=scn.getRenderingContext()
staframe = context.startFrame()
endframe = context.endFrame()
if endframe<staframe: endframe=staframe
curframe = Blender.Get(CURFRAME)
debug(90,'Scene is on frame %i and frame range is %i to %i' % (curframe,staframe,endframe))
return (staframe,endframe,curframe)
########################################
def scrub(): # scrubs to startframe
staFrame,endFrame,curFrame = getRenderInfo()
# eye-candy, go from current to start, fwd or back
if not BATCH:
debug(100, "Positioning to start...")
frameinc=(staFrame-curFrame)/10
if abs(frameinc) >= 1:
for i in range(10):
curFrame+=frameinc
Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects
Blender.Redraw()
Blender.Set(CURFRAME, staFrame)
return
########################################
def bakeBones2(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
scrub()
staFrame,endFrame,curFrame = getRenderInfo()
act = getBakedPoseData(ref_ob, staFrame, endFrame, ACTION_BAKE = True, ACTION_BAKE_FIRST_FRAME = usrACTION) # bake the pose positions of the reference ob to the armature ob
arm_ob.action = act
scrub()
# user comprehension feature - change action name and channel ipo names to match the names of the bone they drive
debug (80,'Renaming each action ipo to match the bone they pose')
act.name = arm_ob.name
arm_channels = act.getAllChannelIpos()
pose= arm_ob.getPose()
pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup
for pbone in pbones:
debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] ))
ipo=arm_channels[pbone.name]
ipo.name = pbone.name # since bone names are unique within an armature, the pose names can be the same since they are within an Action