[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15321] trunk/blender/release/scripts: [ #14405] New python Script - Bake Constraints

Campbell Barton ideasman42 at gmail.com
Mon Jun 23 00:46:02 CEST 2008


Revision: 15321
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15321
Author:   campbellbarton
Date:     2008-06-23 00:46:02 +0200 (Mon, 23 Jun 2008)

Log Message:
-----------
[#14405] New python Script - Bake Constraints
AGAIN PLEAST USE TABS, lost quite some time with mixed tab/space adjustments alone.
Other then that, patch is very useful ;)

---Text from patch submission --- 
Using a slightly revised BPy_Armature, this script takes any non-armature object type and creates an Action that keys
the object location (by default, for every frame). If it is an Armature, it goes into each bone and keys the locrot
of the bone. You can now edit the armature, but the motions still rotate the bones. This enables the next step, re-targeting,
which changes bone lengths to fit a mesh. High-level, we are working toward:

1. import mocap (bvh or c3d)
2. bake to make an action library (using this script)
3. re-target and use the actions to drive/deform any character mesh (theeth)

Modified Paths:
--------------
    trunk/blender/release/scripts/bpymodules/BPyArmature.py

Added Paths:
-----------
    trunk/blender/release/scripts/animation_bake_constraints.py

Added: trunk/blender/release/scripts/animation_bake_constraints.py
===================================================================
--- trunk/blender/release/scripts/animation_bake_constraints.py	                        (rev 0)
+++ trunk/blender/release/scripts/animation_bake_constraints.py	2008-06-22 22:46:02 UTC (rev 15321)
@@ -0,0 +1,800 @@
+#!BPY
+
+"""
+Name: 'Bake Constraints'
+Blender: 246
+Group: 'Animation'
+Tooltip: 'Bake a Constrained object/rig to IPOs'
+Fillename: 'Bake_Constraint.py'
+"""
+
+__author__ = "Roger Wickes (rogerwickes(at)yahoo.com)"
+__script__ = "Bake Constraints"
+__version__ = "0.6"
+__url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"]
+__email__= ["Roger Wickes, rogerwickes at yahoo.com", "scripts"]
+__bpydoc__ = """\
+
+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 to match another's location and/or Tracked to 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 need for the drivers/constraining objects
+
+Developed for use with MoCap data, where a bone is constrained to point at an empty
+moving through space and time. This records the actual locrot of the armature
+so that the motion can be edited, reoriented, scaled, and used as NLA Actions
+
+see also wiki Scripts/Manual/ Sandbox/Animation/Bake_Constraints (tbd)
+
+Usage:<br>
+ - Select the reference Object(s) you want to bake <br>
+ - Set the frame range to bake in the Anim Panel <br>
+ - Set the test code (if you want a self-test) in the RT field in the Anim Panel <br>
+		-- Set RT:1 in the Anim panel to create a test armature <br>
+<br>
+ - Run the script    <br>
+ - The clone copy of the object is created and it has an IPO curve assigned to it. 
+ - The clone shadows the object by an offset locrot (see usrDelta)
+ - That Ipo has Location and Rotation curves that make the shadow mimic the movement of the selected object, 
+		 but without using constraints. Bones move identically in relation to the armature as the reference object
+
+	
+Version History:
+		0.1: bakes Loc Rot for a constrained object
+		0.2: bakes Loc and Rot for the bones within Armature object
+		0.3: UI for setting options
+		0.3.1 add manual to script library
+		0.4: bake multiple objects
+		0.5: root bone worldspace rotation
+		0.6: re-integration with BPyArmature
+		
+License, Copyright, and Attribution:
+	by Roger WICKES  May 2008, released under Blender Artistic Licence to Public Domain
+		feel free to add to any Blender Python Scripts Bundle.
+ Thanks to 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 e.g. camera jitter
+
+Pseudocode (planned versions):
+	Initialize
+	If at least one object is selected
+		For each selected object,
+			create a shadow object
+			remove any constraints on the clone
+			create or reset an ipo curve named like the object
+			for each frame
+				 set the clone's locrot key based on the reference object
+			if it's 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
+	Else you're a smurf
+
+Test Conditions and Regressions:
+	1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level
+	2. armatures, with ipo curve and constraints at the object level
+	3. armatures, with bones that have ipo curves and constraints
+	
+Naming conventions:
+	arm = a specific objec type armature
+	bone = bones that make up the skeleton of an armature
+
+	ob = object, an instance of an object type
+	ebone = edit bone, a bone in edit mode
+	pbone = pose bone, a posed bone in an object
+	tst = testing, self-test routines
+	usr = user-entered or designated stuff  
+
+Pattern Notes (let me know if I've violated any):
+	Bergin Starting,Designing, Programming, Coding
+	Bergin 23 Indent for Structure - I don't like only 2, but the editor is set up that way
+	Bergin 26 Be Spacey Not Tabby - personal frustraion here. workaround is to Format->convert to whitespace
+	Bergin 27 Consistent Capitalization - except Blender, because I love it.
+	Bergin 28 Name Your Constants - not for those I plan on making variable
+	Python 01 Return Everything - I made this one up, all functions and methods end in return
+		even though it is decoration in Python, it helps Python throw an indentation error for typing mistakes
+	Wickes 01 Decorate Your Code - for visual appeal and to ease maintenance, include separators like ######### 
+		to visually distinquish and separate functions, making it quicker to scan through code for methods
+	Wickes 02 Whitespace helps readability - include blanks around = # and lines (after def, after return) to make it stand out and pretty
+
+"""
+########################################
+
+import Blender
+from   Blender import *
+from   Blender.Mathutils import *
+import struct
+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) to conditionally display status/info in console window
+MODE=Blender.Get('rt')  #execution mode: 0=run normal, x=self-test (test error trapping etc)
+DEBUG=100   #how much detail on internal processing for big brother to see
+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=keep parent (if exists), False = breakaway (usually with Real)
+usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin
+	#TODO - i wonder if usrFreeze means we should set Delta to the the difference between the original object and parent?
+# 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
+usrBAKEobjIPO = False # bake the object Ipo? it is useless for MoCap, as we only want the Action, and the Object does not move
+
+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
+#ipoObjectNamePrefix= ""
+#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 error(str):
+	debug(0,'ERROR: '+str)
+	if BATCH == False:
+		Draw.PupMenu('ERROR%t|'+str)
+	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 sortBones(xbones): #returns a sorted list of bones that should be added,sorted based on parent dependency
+	print ('My suggestion would be:')
+#  while there are bones to add,
+#    look thru the list of bones we need to 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's parent
+#               add it now.
+#           else #we need to keep cycling and catch its parent
+#         else it is a root bone
+#           add it
+#       else skip it, it's prego
+#     endfor
+#  endwhile
+	xboneNames=[]
+	for xbone in xbones: xboneNames.append(xbone.name)
+	debug (80,'reference bone order: \n%s' % xboneNames)
+	eboneNames=[]
+	while 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
+	#endwhile
+	debug (80,'clone bone order: \n%s' % eboneNames)
+	return eboneNames
+
+########################################

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list