Si alguien tiene un script para hacer eso que funcione en Blender 2.57, que avise. Además, si alguno de los gurús de Python se atreve a hacerlo, que me diga cuanto me cobraría por si podemos llegar a un acuerdo. Gracias.
Versión para imprimir
Si alguien tiene un script para hacer eso que funcione en Blender 2.57, que avise. Además, si alguno de los gurús de Python se atreve a hacerlo, que me diga cuanto me cobraría por si podemos llegar a un acuerdo. Gracias.
Yo necesitaría tiempo, pero no es muy difícil, creo. Si lo hago no es por dinero, pero, para cuando lo necesitas?
[edito]: estoy buscando la forma de encontrar el parámetro de location para objetos constraint, por que al parecer no se modifican las coordenadas.
Gracias. La prisa es relativa, lo necesitaría para la semana que viene, pero si no puede ser, en cualquier momento me vale, porque siempre uso constraints y muchas veces me he encontrado con ese problema.
Hm. No es tan fácil como buscar ese parámetro, porque los huesos que no tienen curvas de animación, están (si no me equivoco) a cero sin importar lo que hagan por otros medios, como constraints o movimientos del padre. Creo que hay que usar matrices y calcular la posición en coordenadas del world, pero no me hagas mucho caso.
Había un script que hizo seyacat hace mucho que bakeaba la animación del game-engine y creo que usaba ese método, lo he buscado por si le sirve a alguien de ayuda, pero no lo encuentro.
Este script es muy interesante para los que tenemos que lidiar con exportaciones a otros softwares, así que, si lo hicieses (tú o cualquier otro) estaría encantado de pagar por el y si insistes en no hacerlo por dinero, pues no sé, te presento a alguna amiga que este buena.
Vaya, te agradezco el ofrecimiento, pero se me complica. Estoy viendo los parámetros entre render y render. Es evidente que hace falta esté parámetro.
Si encuentro este punto ya casi que lo tengo.
Edito, encontré la opción, ahora estoy interpretándola para recuperarla.
Si, es con matrices, evidentemente. Tengo que estudiar eso ya que es un tema pendiente. Me parece que te la debo. Debería haber un valor resultante eh, sería muy bueno.
Ok, no te preocupes, se agradece igualmente. A ver si algún otro forero se anima.
Bueno, encontré algo a ver si lo puedo hacer. Si logro te digo.
Import Bpy. Import math.
#Bpy, data, objects[Cube.001].rotation_euler = Bpy, data, objects[Cube].matrix_world, to_euler().
Start=1.
End=50.
While start < end.
Bpy, data, objects[Cube].rotation_euler = Bpy, data, objects[Cube].matrix_world, to_euler().
Bpy, data, objects[Cube].keyframe_insert(rotation_euler, frame=start).
Bpy, context, scene, frame_current= start.
Print(Bpy, data, objects[Cube].matrix_world, to_euler()).
Print(start).
Start+=1.
No sé cómo resolver el problema de refresco.
Es un wip, hay que ver cómo solucionar eso.
Bien, logré con un cubo. Aún no entiendo cómo es la Matrix de un Joint. Te dejo el blend. Abrilo y dale manualmente run script, run script, run script, ya que el for, while y todo eso no funciona.
Vamos avanzando.
Me estas alegrando el día. Ahora estoy en el trabajo, pero esta tarde le echo un vistazo.
Ostras, que cortito. Me encanta que el Api sea ahora más completo y se pueda hacer esto más fácilmente. Bueno, he probado tu ejemplo y funciona perfecto, pero tendré que esperar a ver si puedes hacer que funcione con Bones o no me servirá, además de que son muchos Bones lo suyo sería seleccionar (en modo pose) todos los que necesitase bakear y que el script lo haga, y ya para terminar de pulirlo, si pudiese bakear la posición y el tamaño, ya sería la hostia, aunque lo que realmente necesito ahora es el bakeo de la rotación, porque al ser una jerarquía, si roto el padre, lógicamente el hijo cambia de posición automáticamente. Gracias.
Posdata: vaya. Qué gustillo me ha dado ver la curva de animación bakeada.
Hola. Yo no controlo Python, pero como la lógica es la misma en todos los lenguajes, voy a intentar echar una mano. Creo que entiendo porqué no te funciona el bucle, bueno no es que no te funcione, sino que la primera vez que insertas un keyframe el objeto ya no va a rotar, porqué ese keyframe se extrapola durante toda la animación, así que, si no me equivoco, lo que hay que hacer es usar dos bucles, en el primero se guardan los valores en un array y en el segundo se crean los keyframes.
¿Tiene sentido?
Mira, he encontrado este script viejo de la 2.4x del que quizás puedas aprovechar alguna parte:
Código:#.Bpy. Name: bake constraints.
Blender: 246.
Group: animation.
Toltip: bake a constrained object/rig todo Ipos.
Fillename: bake_constraint, py.
_author__ = Roger wickes (rogerwickes(at)yahoo, com).
_script__ = animation bake constraints.
_versión__ = 0.7.
_url__ = [commúnicate problems and errors
Bake_constraints.
This script bakes the real-world locrot of an object (the net effect of any constraints -.
(Copy, limit, track, follow, - That affect location, rotation).
(Usually one constrained todo match another location and/or tracked todo another).
And creates a clone with a set of ipo curves named ipo<objname>.
These curves control a non-constrained object and thus make it Mimic the constrained object.
Actions can be then be edited without the ned for the drivers/constraining objects.
Developed for use with Mocap data, where a bone is constrained todo point at an empty.
Moving th rouge space and time. This récords the actual locrot of the armature.
So that the motion can be edited, reoriented, scaled, and used as NLA actions.
Se a los wiki scripts/manual/ tutorial/motion capture .
Usage: .
Select the reference object(s) you want todo bake .
Set the frame range todo bake in the Anim panel .
Set the test code (if you want a self-test) in the rt field in the Anim panel t-- Set rt:1 todo create a test armature t-- Set rt: up to 100 for more debug messages and status updates .
Run the script .
The clone copy of the object is created and it has an ipo curve assigned todo it. .
The clone shadows the object by an offset locrot (se usrdelta) .
That object has ipo location and rotation curves that make the clone Mimic the movement tof the selected object, but without using constraints. .
If the object was an armature, the clone Bones move idéntically in relation todo the toriginal armature, and an action is created that drivers the bone movements. .
Versión history:
0.1: bakes Loc root for a constrained object t0.2: bakes Loc and root for the Bones within armature object t0.3: UI for setting options t0.3.1 add manual todo script library t0.4: bake múltiple objects t0.5: root bone worldspace rotation t0.6: re-integration with bpyarmature t0.7: bakes parents and leaves clones selected.
License, copyright, and attribution:
By Roger wickes may 2008, released under Blender artistic licence todo public domain.
Fel free todo add todo any Blender Python scripts bundle.
Thanks todo Jean-baptiste perin, ideasman42 (Campbell Barton), basil_fawlty/cage_drei (Andrew cruse).
Much lifted/learned from Blender.org/documentation/245pytondoc and wiki.
Some modules based on c3d_import, py, poselib16.py and ipo/armature code examples eh, g, Camera Jitter.
Pseudocode:
Initialize tif at least one object is selected for each selected object create a cloned object remove any constraints on the clone create or reset an ipo curve named like the object for each frame set the clone locrot key based on the reference object if it an armature create an action (which is an ipo for each bone) for each frame of the animation for each bone in the armature set the key telse youre a smurf.
Test conditions and regressions:
1. (v0.1) non-armatures (the Cube), with ipo curve and constraints at the object level t2, armatures, with ipo curve and constraints at the object level t3, armatures, with Bones that have ipo curves and constraints t4, objects without parents, children with unselected parents, select children first.
Naming conventions:
Arm = a specific objec type armature tbone = Bones that make up the skeleton of an armature tob = object, an instance of an object type tebone = edit bone, a bone in Edit Mode tpbone = postura bone, a posed bone in an object ttst = testing, self-test routines tusr = user-entered or designated Stuff.
########################################.
Import Blender.
From Blender import *.
From Blender. Mathutils import *.
Import structure.
Import string.
Import Bpy.
Import bpymessages.
Import bpyarmature.
# reload(bpyarmature).
From bpyarmature import getbakedposedata.
Vector= Blender. Mathutils. Vector.
Euler= Blender. Mathutils. Euler.
Matrix= Blender. Mathutils. Matrix #invert() function at least.
Rotationmatrix = Blender. Mathutils. Rotationmatrix.
Translationmatrix= Blender. Mathutils. Translationmatrix.
Quaternion = Blender. Mathutils. Quaternion.
Vector = Blender. Mathutils. Vector.
Pose_xform= [blender. Object. Pose. Loc, Blender. Object. Pose. Rot].
#=================
# global variables.
#=================
# set senstitivity for displaying debug/console messages. 0=none, 100=max.
# then call debug(num, string) todo conditionally display status/información 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 todo se, 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 todo a parent.
Cordinate_systems = [local,real].
Cord_local = 0.
Cord_real = 1.
# user settings - Change these options manually or vía GUI (future todo).
Usrcord = cord_real # what the user wants.
Usrparent = false # true=clone keps original parent, false = clone parent is the clone of the original parent (if cloned).
Usrfreze = 2 #2=yes, 0=no. Frezes shadow object in place at current frame as origin.
# delta is amount todo 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 root XYZ.
Usraction = true # offset baked action frames todo start at frame 1.
Curframe = curframe #keyword todo 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 todo the armature # bonespace - The Matrix of the bone in relation todo 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 todo grad.
Blender_version = Blender. Get(versión).
# 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 tif debug >= num:
If Batch == false:
Print debug: [:num/10+7]+msg #todo: else write out todo file (runs faster if it doesnt have todo display details) treturn.
########################################.
Def error(str):
Debug(0,error: +str) tif Batch == false:
Draw. Pupmenu (error%t|+str) treturn.
########################################.
Def getrenderinfo ():
Context=scn, getrenderingcontext() tstaframe = context, startframe () tendframe = context, endframe () tif endframe<staframe: endframe=staframe tcurframe = Blender. Get(curframe) tdebug(90,scene is on frame %i and frame range is %i todo %i % (curframe, staframe, endframe)) treturn (staframe, endframe, curframe).
########################################.
Def sortobjects(obs): #returns a list of objects sorted based on parent dependency tobclones= [] twhile len(obclones) < len(obs):
For ob in obs:
If not ob in obclones:
Par= ob, getparent() #if no parent, or the parent is not scheduled todo be cloned if par==none:
Obclones, append(ob) # add the independent elif par not in obs: # parent Will not be cloned obclones, append(ob) # add the child elif par in obclones: # is it on the listí obclones, append(ob) # add the child # parent may be a child, so it Will be caught next time thru tdebug(100,clone object order: \n%s % obclones) treturn obclones # ordered list of (ob, par) tuples.
########################################.
Def sortbones(xbones): #returns a sorted list of Bones that should be added, sorted based on parent dependency.
# while there are Bones todo add.
# look thru the list of Bones we ned todo add.
# if we have not already added this bone.
# if it does not have a parent.
# add it.
# else, it has a parent.
# if we already added it parent.
# add it now.
# else #we ned todo kep cycling and catch its parent.
# else it is a root bone.
# add it.
# else Skip it, it already in there.
# endfor.
# endwhile txbonenames=[] tfor xbone in xbones: xbonenames, append(xbone, name) tdebug (80,reference bone order: \n%s % xbonenames) tebonenames=[] twhile len(ebonenames) < len(xbonenames):
For xbone in xbones:
If not xbone, name in ebonenames:
If not xbone, parent:
Ebonenames, append(xbone, name) else:
If xbone, parent, name in ebonenames:
Ebonenames, append(xbone, name) #else Skip it #endif #else prego #endfor t#endwhile tdebug (80,clone bone order: \n%s % ebonenames) treturn ebonenames.
########################################.
Def dupliarmature (ob): #makes a copy in current scn of the armature used by ob and its Bones tob_mat = ob, matrixworld tob_data = ob, getdata () tdebug(49,reference object uses %s % ob_data) tarm_ob = armature. Get(ob_data, name) #the armature used by the passed object tarm = Blender. Armature. New() tdebug(20,cloning armature %s todo create %s % (arm_ob, name, arm, name)) tarm, drawtype = armature. Stick #set the draw type tarm, makeeditable () #enter editmode t# for each bone in the object armature txbones=ob, data, Bones, values() tusrspace = 0 #0=armature, 1=local tspace=[bone_spaces[usrspace][0] t#we have todo make a list of Bones, then figure out our parents, then add todo the arm t#when creating a child, we cannot enlace todo a parent if it does not yet exist in our armature tebones = [] #list of the Bones i want todo create for my arm tebonenames = sortbones(xbones) ti=0 t# error(Bones sorted, continue? ) tfor abone in ebonenames: #set all editable attributes todo fully define the bone for bone in xbones:
If bone, name == abone: break # get the reference bone ebone = armature. Editbone () #throw me ha bone, bone-man ebones, append(ebone) #youre on my list, buddy ebone, name = bone, name ebone, headradius = bone, headradius ebone, tailradius = bone, tailradius ebone.weight = bone.weight ebone, options = bone, options t ebone, head = bone, head[space] #dictionary lokups ebone, tail = bone, tail[space] ebone, Matrix = bone, Matrix[space] ebone, roll = bone, roll[space] debug(30,generating new %s as child of %s % (bone, bone, parent)) if bone, hasparent():
# parent=bone, parent, name.
# debug(100,looking for %s % parent).
# for parbone in xbones: if parbone, name == parent: break # get the parent bone.
# ebone, parent = arm, Bones[ebones[j].name] ebone, parent = arm, Bones[bone, parent, name].
# else:
# ebone, parent = none debug(30,generating new editbone %s as child of %s % (ebone, ebone, parent)) arm, Bones[ebone, name] = ebone # i would have expected an append or add function, but this works tdebug (100,arm, Bones: \n%s % arm, Bones) tdebug (20,cloned %i Bones now in armature %s %(len(arm, Bones), arm, name)) tmyob = scn, objects, new(arm) #interestingly, object must be created before tarm, update () #armature can be saved tdebug(40,duparm finished %s instanced as object %s % (arm, name, myob, getname ())) Tprint ob, Matrix Tprint myob, Matrix treturn myob.
########################################.
Def scrub(): # Scrubs todo startframe tstaframe, endframe, curframe = getrenderinfo () t# eye-Candy, go from current todo start, fwd or back tif not Batch:
Debug(100, positioning todo 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() tblender. Set(curframe, staframe) treturn.
########################################.
Def bakebones(ref_ob, arm_ob): #copy postura from ref_ob todo arm_ob tscrub() tstaframe, endframe, curframe = getrenderinfo () tact = getbakedposedata (ref_ob, staframe, endframe, action_bake = true, action_bake_first_frame = usraction) # bake the postura positions of the reference ob todo the armature ob tarm_ob, action = ACT tscrub() t# user comprehension característica - Change action name and channel ipo names todo match the names of the bone they drive tdebug (80,renaming each action ipo todo match the bone they pose) tact, name = arm_ob, name tarm_channels = ACT, getallchannelipos() tpose= arm_ob, getpose () tpbones= pose, Bones, values() #we want the Bones themselves, not the dictionary lookup tfor 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 postura names can be the same since they are within an action treturn.
########################################.
Def getorcreatecurve (IPO, curvename):
Tretrieve or create a Blender ipo curve named c{curvename} in the c{ipo} ipo teither an ipo curve named c{curvename} exists before the call then this curve is returned tor such a curve doesnt exist before the call, then it is created into the c{ipo} ipo and returned ttry:
Mycurve = IPO, getcurve (curvename) if mycurve.= none:
Pass else:
Mycurve = IPO, addcurve (curvename) texcept:
Mycurve = IPO, addcurve (curvename) treturn mycurve.
########################################.
Def erasecurve (IPO, numcurves):
Debug(90,erasing %i curves for % % (numcurves, ipo. Getname ())) tfor i in range (numcurves):
Nbbezpoints= IPO, getnbezpoints(i) for in range (nbbezpoints):
Ipo, delbezpoint(i) treturn.
########################################.
Def resetipo (ipo):
Debug(60,resetting ipo curve named %s %IPO, name) tnumcurves = IPO, getncurves() #like locx, locy, etc tif numcurves > 0:
Erasecurve (IPO, numcurves) #erase data if one exists treturn.
########################################.
Def resetipos(ob): #resets all ipo curvess assocated with an object and its Bones tdebug(30,resetting any ipo curves linked todo %s %ob, getname ()) tipo = ob, getipo () #may be none tiponame = IPO, getname () #name of the ipo that guides/controls this object tdebug(70,object ipo is %s %iponame) ttry:
Ipo = ipo. Get(iponame) texcept:
Ipo = ipo. New(object, iponame) tresetipo (ipo) tif ob, gettype () == armature:
Arm_data=ob, getdata () Bones=arm_data, Bones, values() for bone in Bones:
#for each bone: get the name and chek for a pose ipo debug(10,processing + bone, name) treturn.
########################################.
Def parse (string, delim):
Index = string, find(delim) # -1 if not found, else pointer todo delim tif index+1: return string[:index] treturn string.
########################################.
Def newipo (iponame): #add a new ipo object todo the Blender scene tipo=blender. Ipo. New(object, iponame) tipo, addcurve (locx) tipo, addcurve (locy) tipo, addcurve (locz) tipo, addcurve (rotx) tipo, addcurve (roty) tipo, addcurve (rotz) treturn ipo.
########################################.
Def makeupaname (type, name): #i know this exists in Blender somewhere tdebug(90,Making up a new %s name using %s as a basis. % (type, name)) tname = (parse (name.)) tif type == ipo:
Iponame = name # maybe we get Lucky today ext = 0 extlen = 3 # 3 digit extensiones, like hello.002 success = false while not(success):
Try:
Debug(100,trying %s % iponame) ipo = ipo. Get(iponame) #that one exists if we get here, add on extensión and kep trying ext +=1 if ext>=10**extlen: extlen +=1 # go todo more digits if 999 not found iponame = %s.%s % (name, str(ext), zfill(extlen)) except: # could not find it success = true name=iponame telse:
Debug (0,fatal error: i dont know how todo make up a new %s name based on %s % (type, ob)) return none treturn name.
########################################.
Def createipo (ob): #create an ipo and curves and enlace them todo this object t#first, we have todo create a unique name t#try first with just the name of the object todo kep things simple tiponame = makeupaname (IPO, ob, getname ()) # make up a name for a new ipo based on the object name tdebug(20,ipo and locrot curves called %s % iponame) tipo=newipo (iponame) tob, setipo (ipo) #link them treturn ipo.
########################################.
Def getloclocal(ob):
Key = [ ob. Locx ob. Locy ob. Locz ob. Rotx*r2d, #get the curves in this order ob. Roty*r2d ob. Rotz*r2d ] treturn key.
########################################.
Def getlocreal(ob):
Obmatrix = ob, matrixworld #gracias you ideasman42 tloc = obmatrix.translationpart() trot = obmatrix.toeuler() tkey = [ Loc.x Loc, y Loc, z root.x/10 root, y/10 root, z/10 ] treturn key.
########################################.
Def getlocrot(ob, space):
If space in xrange (len(cordinate_systems)):
If space == cord_local:
Key = getloclocal(ob) return key elif space == cord_real:
Key = getlocreal(ob) return key else: #hey, programmers make mistakes todo debug(0,fatal error: getloc called with %i % space) treturn.
########################################.
Def getcurves(ipo):
Ipues = [ ipo[ipo. Ob_locx] ipo[ipo. Ob_locy] ipo[ipo. Ob_locz] ipo[ipo. Ob_rotx], #get the curves in this order ipo[ipo. Ob_roty] ipo[ipo. Ob_rotz] ] treturn Ipos.
########################################.
Def addpoint(time, keylocrot, Ipos):
If blender_version < 245:
Debug(0,warning: addpoint uses beztriple) tfor i in range (len(Ipos)):
Point = beztriple. New() #this was new with Blender 2.45 Api point, PT = (time, keylocrot[i]) point, handletypes = [1,1] Ipos[i].append(point) treturn Ipos.
########################################.
Def bakeframes(ob, myipo): #bakes an object in a scene, returning the ipo containing the curves tmyiponame = myipo, getname () tdebug(20,baking frames for scene %s object %s todo ipo %s % (scn, getname (), ob, getname (), myiponame)) tipues = getcurves(myipo) t#todo: GUI setup idea: myoffset t# reset action todo start at frame 1 or at location tmyoffset=0 #=1-staframe t#lop th rouge frames in the animation. Often, there is rollup and the Mocap starts late tstaframe, endframe, curframe = getrenderinfo () tfor frame in range (staframe, endframe+1):
Debug(80,baking frame %i % frame) #tell Blender todo advace todo frame Blender. Set(curframe, frame) # computes the constrained location of the real objects if not Batch: Blender. Redraw() # no secrets, let user se what we are doing t #using the constrained Loc root of the object, set the location of the unconstrained clone. Yea. Clones are fremen key = getlocrot(ob, usrcord) #a key is a set of specifed exact channel values (locrotscale) for a certain frame key = [a+b for a, b in zip(key, usrdelta)] #offset todo the new location myframe= frame+myoffset Blender. Set(curframe, myframe) t time = Blender. Get(curtime) #for beztriple ipues = addpoint(time, key, Ipos) #add this data at this time todo the Ipos debug(100,%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f % (myiponame, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5])) t# eye-Candy - Smoothly rewind the animation, showing now how the clone match moves tif endframe-staframe <400 and not Batch:
For frame in range (endframe, staframe,-1): #rewind Blender. Set(curframe, frame) # computes the constrained location of the real objects Blender. Redraw() tblender. Set(curframe, staframe) tblender. Redraw() treturn Ipos.
########################################.
Def duplicatelinked(ob):
Obtype = ob, type tdebug(10,duplicating %s object named %s % (obtype, ob, getname ())) tscn, objects, selected = [ob].
## rdw: simplified by just duplicating armature, kept code as reference for creating armatures.
## disadvantage is that you cant have clone as stick and original as octahedron.
## since they share the same armature. User can click make single user button.
## if obtype == armature: #build a copy from scratch.
## myob= dupliarmature (ob).
## else:
Blender. Object. Duplicate () # duplicate linked, including postura constraints tmyobs = object. Getselected() #duplicate is top on the list tmyob = myobs[0] tif usrparent == false:
Myob, clrparent(usrfreze) tdebug(20,=myob= was created as %s % myob, getname ()) treturn myob.
########################################.
Def removeconstraints(ob):
For const in ob, constraints:
Debug(90,removed %s => %s % (ob, name, const)) ob, constraints, remove (const) treturn.
########################################.
Def removeconstraintsob(ob): # from object or armature tdebug(40,removing constraints from +ob, getname ()) tif blender_version > 241: #constraints module not available before 242 removeconstraints(ob) if ob, gettype () == armature:
Pose = ob, getpose () for pbone in pose, Bones, values():
#bone = pose, Bones[bonename] removeconstraints(pbone) #should a los chek if it is a deflector?
Return.
########################################.
Def delinkob(type, ob): #remove linkages tif type == ipo:
Success = ob, clearipo () #true=there was one if success: debug(80,delinked ipo curve todo %s % ob, getname ()) treturn.
########################################.
Def bakeobject(ob): #bakes the Core object locrot and assigns the ipo todo a clone tif ob.= none:
# clone the object - Duplicate it, clean the clone, and create an ipo curve for the clone myob = duplicatelinked(ob) #clone it myob, setname (usrobjectnameprefix + ob, getname ()) removeconstraintsob(myob) #my object is a free man delinkob(IPO, myob) #kids, it not nice todo share, youve ben lied todo if ob, gettype ().= armature: # baking armatures is based on Bones, not object myipo = createipo (myob) #create own ipo and curves for the clone object ipues = bakeframes(ob, myipo) #bake the locrot for this obj for the scene frames treturn myob.
########################################.
Def bake (ob, par): #bakes an object of any type, linking it todo parent tdebug(0,baking %s object %s % (ob, gettype (), ob)) tclone = bakeobject(ob) #creates and bakes the object motion tif par.= none:
Par, makeparent([clone]) debug(20,assigned object todo parent %s % par) tif ob, gettype () == armature:
## error(object baked. Continúe with Bones? ) bakebones(ob, clone) #go into the Bones and copy from -> todo in frame range t#future idea: bakemesh (net result of shape keys, Softbody, Cloth, fluidsim,) treturn clone.
########################################.
Def tstcreatearm(): #create a test armature in scene t# Rip-of from http://www.blender.org/documentation/245pythondoc/pose-module.html - Thank you tdebug(0,Making test armature) t# new armature tarm_data= armature. New(myarmature) Tprint arm_data tarm_ob = scn, objects, new(arm_data) tarm_data, makeeditable () t# add 4 Bones tebones = [armature. Editbone (), armature. Editbone (), armature. Editbone (), armature. Editbone ()] t# name the editbones tebones[0].name = bone.001 tebones[1].name = bone.002 tebones[2].name = bone.003 tebones[3].name = bone.004 t# assing the editbones todo the armature tfor eb in ebones:
Arm_data, Bones[eb, name]= eb t# set the locations of the Bones tebones[0].head= Mathutils. Vector(0,0,0) tebones[0].tail= Mathutils. Vector(0,0,1) #tip tebones[1].head= Mathutils. Vector(0,0,1) tebones[1].tail= Mathutils. Vector(0,0,2) tebones[2].head= Mathutils. Vector(0,0,2) tebones[2].tail= Mathutils. Vector(0,0,3) tebones[3].head= Mathutils. Vector(0,0,3) tebones[3].tail= Mathutils. Vector(0,0,4) tebones[1].parent= ebones[0] tebones[2].parent= ebones[1] tebones[3].parent= ebones[2] tarm_data, update () t# done with editing the armature t# assing the postura animation tarm_pose = arm_ob, getpose () tact = arm_ob, getaction() tif not ACT: # add a postura action if we dont have one ACT = armature. Nla. Newaction() ACT, setactive (arm_ob) txbones=arm_ob, data, Bones, values() tpbones = arm_pose, Bones, values() tframe = 1 tfor pbone in pbones: # set Bones todo no rotation pbone, quat[:] = 1.000,0.000,0.000,0.0000 pbone, insertkey(arm_ob, frame, object. Pose. Rot) t# set a diferent rotation at frame 25 tpbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000 tpbones[1].quat[:] = 1.000,0.6000,0.5000,0.40000 tpbones[2].quat[:] = 1.000,0.1000,0.3000,0.40000 tpbones[3].quat[:] = 1.000,-0.2000,-0.3000,0.30000 tframe = 25 tfor i in xrange (4):
Pbones[i].insertkey(arm_ob, frame, object. Pose. Rot) tpbones[0].quat[:] = 1.000,0.000,0.000,0.0000 tpbones[1].quat[:] = 1.000,0.000,0.000,0.0000 tpbones[2].quat[:] = 1.000,0.000,0.000,0.0000 tpbones[3].quat[:] = 1.000,0.000,0.000,0.0000 tframe = 50 tfor pbone in pbones: # set Bones todo no rotation pbone, quat[:] = 1.000,0.000,0.000,0.0000 pbone, insertkey(arm_ob, frame, object. Pose. Rot) treturn arm_ob.
########################################.
Def tstmoveob(ob): # makes a simple locrot animation of object in the scene tanim = [ #loc root/10 # (0,0,0, 0, 0, 0), #frame 1 origin (1,0,0, 0, 0, 0), #frame 2 (1,1,0, 0, 0, 0) (1,1,1, 0, 0, 0) (1,1,1,4.5, 0, 0) (1,1,1,4.5,4.5, 0) (1,1,1,4.5,4.5,4.5) ] tspace = cord_local tipo = createipo (ob) #create an ipo and curves for this object tipues = getcurves(ipo) t# span this motion over the currently set Anim range t# todo set points, y ned time but do not know how it is computed, so Will have todo advance the animation tstaframe, endframe, curframe = getrenderinfo () tframe = staframe #x position of new ipo datapoint, set todo staframe if you want a match tframedelta=(endframe-staframe)/(len(anim)) #accomplish the animation in frame range tfor key in Anim: #efectively does a getlocrot() #tell Blender todo advace todo frame Blender. Set(curframe, frame) # computes the constrained location of the real objects time = Blender. Get(curtime) ipues = addpoint(time, key, Ipos) #add this data at this time todo the Ipos debug(100,%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f % (IPO, name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5])) frame += framedelta tblender. Set(curframe, curframe) # reset bak todo where we started treturn.
#=================
# programa template.
#=================
########################################.
Def main():
# return code set vía rt button in Blender buttons scene context Anim panel tif mode == 1: #create test armature #1 ob = tstcreatearm() # make test arm and select it tstmoveob(ob) scn, objects, selected = [ob] tobs= Blender. Object. Getselected() #scn, objects, selected tobs= sortobjects(obs) tdebug(0,baking %i objects % len(obs)) tif len(obs) >= 1: # user might have múltiple objects selected i= 0 clones=[] # my clone army for ob in obs:
Par= ob, getparent() if not usrparent:
If par in obs:
Par= clones[obs, index(par)] clones, append(bake (ob, par)) scn, objects, selected = clones telse:
Error(pléase select at least one object) treturn.
########################################.
Def benchmark(): # this lets you benchmark (time) the script running duration twindow.waitcursor(1) tt = Sys, time () tdebug(60,%s began at %.0f %(__script__, Sys, time ())) t# run the function on the active scene tin_editmode = window. Editmode () tif in_editmode: window. Editmode (0) tmain() tif in_editmode: window. Editmode (1) t# timing the script is a god bien todo be aware on any speed hits when scripting tdebug(0,%s script finished in %.2f seconds % (__script__, Sys, time ()-t)) twindow.waitcursor(0) treturn.
########################################.
# this lets you can import the script without running it.
If __name__ == __main__:
Debug(0, -) tdebug(0, %s %s script begins with mode=%i debug=%i Batch=%s % (__script__,__versión__,mode,debug,Batch)) tbenchmark().
Esto serviría? Esta en Blender 2.56 ya que en 2.57 no me funciona bien el apply visual transform todo pose. Aquí un archivo para que testes.
Archivo adjunto 146102
Dale a run script y en el panel properties, en object, saldrá un botón que al presionar va guardando frame a frame, solo es pulsar como loco.
Si funcionara, ya se mira de mejorar. Suerte.
Espero que te sirva.
Hola rulflink, gracias por tu ayuda. He probado tu ejemplo, pero al menos a mí no me funciona o sea, pulso el botón para cada frame y veo cómo se crean los keyframes, pero después le quito el constraint al hueso y al pulsar Alt+a la animación resultante no se parece en nada a la original.