Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjy Cook <benjycook@hotmail.com>2011-07-08 00:46:35 +0400
committerBenjy Cook <benjycook@hotmail.com>2011-07-08 00:46:35 +0400
commit46f938e70b081d20da5dac2cbaca6900d9e9b2ad (patch)
tree05bc559c9fae10ba095ec7f62a3bbf43113b34ba /release/scripts
parent6f5b5ac3c921216306972d24fab1a778c561571a (diff)
Added baking/unbaking functionality to constraint system. Retargeting now adds/manages 2 new NLA Tracks as planned. Modified bl_operatores/nla.py slightly to use it instead of creating my own bake function (now supports baking to a specific action, vs always creating a new one), but this does not break using the function in the old way.
Diffstat (limited to 'release/scripts')
-rw-r--r--release/scripts/modules/mocap_constraints.py95
-rw-r--r--release/scripts/modules/retarget.py15
-rw-r--r--release/scripts/startup/bl_operators/nla.py26
-rw-r--r--release/scripts/startup/ui_mocap.py12
4 files changed, 124 insertions, 24 deletions
diff --git a/release/scripts/modules/mocap_constraints.py b/release/scripts/modules/mocap_constraints.py
index ec587c987f6..07ebb01ea3d 100644
--- a/release/scripts/modules/mocap_constraints.py
+++ b/release/scripts/modules/mocap_constraints.py
@@ -20,6 +20,7 @@
import bpy
from mathutils import *
+from bl_operators import nla
### Utility Functions
@@ -96,7 +97,7 @@ def updateConstraintBoneType(m_constraint, context):
# Function that copies all settings from m_constraint to the real Blender constraints
# Is only called when blender constraint already exists
-def setConstraintFraming(m_constraint, cons_obj, real_constraint):
+def setConstraintFraming(m_constraint, cons_obj, obj, real_constraint):
if isinstance(cons_obj, bpy.types.PoseBone):
fcurves = obj.animation_data.action.fcurves
else:
@@ -129,7 +130,7 @@ def setConstraint(m_constraint):
real_constraint = cons_obj.constraints[m_constraint.real_constraint]
#frame changing section
- setConstraintFraming(m_constraint, cons_obj, real_constraint)
+ setConstraintFraming(m_constraint, cons_obj, obj, real_constraint)
#Set the blender constraint parameters
if m_constraint.type == "point":
@@ -176,4 +177,92 @@ def setConstraint(m_constraint):
real_constraint.distance = m_constraint.targetDist
# active check
- real_constraint.mute = not m_constraint.active
+ real_constraint.mute = (not m_constraint.active) and (m_constraint.baked)
+
+
+def updateBake(self, context):
+ if self.baked:
+ print("baking...")
+ bakeConstraint(self)
+ else:
+ print("unbaking...")
+ unbakeConstraint(self)
+
+
+def bakeTransformFK(anim_data, s_frame, e_frame, end_bone, bones, cons_obj):
+ mute_ik = False
+ for bone in bones:
+ bone.bone.select = False
+ ik = hasIKConstraint(end_bone)
+ if not isinstance(cons_obj, bpy.types.PoseBone) and ik:
+ if ik.chain_count == 0:
+ selectedBones = bones
+ else:
+ selectedBones = [end_bone] + end_bone.parent_recursive[:ik.chain_count - 1]
+ mute_ik = True
+ else:
+ selectedBones = [end_bone]
+ print(selectedBones)
+ for bone in selectedBones:
+ bone.bone.select = True
+ anim_data.action = nla.bake(s_frame,
+ e_frame, action=anim_data.action)
+ return mute_ik
+
+
+def bakeConstraint(m_constraint):
+ obj = bpy.context.active_object
+ bones = obj.pose.bones
+ end_bone = bones[m_constraint.constrained_bone]
+ cons_obj = getConsObj(end_bone)
+ scene = bpy.context.scene
+ s_frame = scene.frame_start
+ e_frame = scene.frame_end
+ mute_ik = bakeTransformFK(obj.animation_data, s_frame, e_frame, end_bone, bones, cons_obj)
+ if mute_ik:
+ ik_con = hasIKConstraint(end_bone)
+ ik_con.mute = True
+ real_constraint = cons_obj.constraints[m_constraint.real_constraint]
+ real_constraint.mute = True
+ constraintTrack = obj.animation_data.nla_tracks["Mocap constraints"]
+ constraintStrip = constraintTrack.strips[0]
+ constraintStrip.action_frame_start = s_frame
+ constraintStrip.action_frame_end = e_frame
+ constraintStrip.frame_start = s_frame
+ constraintStrip.frame_end = e_frame
+
+
+def unbakeConstraint(m_constraint):
+ # to unbake a constraint we need to delete the whole strip
+ # and rebake all the other constraints
+ obj = bpy.context.active_object
+ bones = obj.pose.bones
+ end_bone = bones[m_constraint.constrained_bone]
+ cons_obj = getConsObj(end_bone)
+ scene = bpy.context.scene
+ s_frame = scene.frame_start
+ e_frame = scene.frame_end
+ constraintTrack = obj.animation_data.nla_tracks["Mocap constraints"]
+ constraintStrip = constraintTrack.strips[0]
+ action = constraintStrip.action
+ for fcurve in action.fcurves:
+ action.fcurves.remove(fcurve)
+ for other_m_constraint in obj.data.mocap_constraints:
+ if m_constraint != other_m_constraint:
+ bakeConstraint(other_m_constraint)
+ # It's a control empty: turn the ik back on
+ if not isinstance(cons_obj, bpy.types.PoseBone):
+ ik_con = hasIKConstraint(end_bone)
+ if ik_con:
+ ik_con.mute = False
+ real_constraint = cons_obj.constraints[m_constraint.real_constraint]
+ real_constraint.mute = False
+
+
+def hasIKConstraint(pose_bone):
+ #utility function / predicate, returns True if given bone has IK constraint
+ ik = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"]
+ if ik:
+ return ik[0]
+ else:
+ return False
diff --git a/release/scripts/modules/retarget.py b/release/scripts/modules/retarget.py
index 6409c5ed535..885a457061a 100644
--- a/release/scripts/modules/retarget.py
+++ b/release/scripts/modules/retarget.py
@@ -374,6 +374,21 @@ def totalRetarget():
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_name(name=inter_obj.name, extend=False)
bpy.ops.object.delete()
+ anim_data = enduser_obj.animation_data
+ mocapAction = anim_data.action
+ mocapAction.name = "Base Mocap Action"
+ anim_data.use_nla = True
+ mocapTrack = anim_data.nla_tracks.new()
+ mocapTrack.name = "Base Mocap Track"
+ mocapStrip = mocapTrack.strips.new("Base Mocap Action", s_frame, mocapAction)
+ constraintTrack = anim_data.nla_tracks.new()
+ constraintTrack.name = "Mocap constraints"
+ constraintAction = bpy.data.actions.new("Mocap constraints Action")
+ constraintStrip = constraintTrack.strips.new("Mocap constraints Action", s_frame, constraintAction)
+ #constraintStrip.frame_end = e_frame
+ anim_data.nla_tracks.active = constraintTrack
+ anim_data.action = constraintAction
+
if __name__ == "__main__":
totalRetarget()
diff --git a/release/scripts/startup/bl_operators/nla.py b/release/scripts/startup/bl_operators/nla.py
index 7a5fa552ede..e0b5a11dc78 100644
--- a/release/scripts/startup/bl_operators/nla.py
+++ b/release/scripts/startup/bl_operators/nla.py
@@ -83,7 +83,7 @@ def bake(frame_start,
do_pose=True,
do_object=True,
do_constraint_clear=False,
- ):
+ action=None):
scene = bpy.context.scene
obj = bpy.context.object
@@ -120,7 +120,8 @@ def bake(frame_start,
# incase animation data hassnt been created
atd = obj.animation_data_create()
- action = bpy.data.actions.new("Action")
+ if action == None:
+ action = bpy.data.actions.new("Action")
atd.action = action
if do_pose:
@@ -253,37 +254,38 @@ class BakeAction(bpy.types.Operator):
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
-
+
#################################
+
class ClearUselessActions(bpy.types.Operator):
'''Mark actions with no F-Curves for deletion after save+reload of file preserving "action libraries"'''
bl_idname = "anim.clear_useless_actions"
bl_label = "Clear Useless Actions"
bl_options = {'REGISTER', 'UNDO'}
-
- only_unused = BoolProperty(name="Only Unused",
+
+ only_unused = BoolProperty(name="Only Unused",
description="Only unused (Fake User only) actions get considered",
default=True)
-
+
@classmethod
def poll(cls, context):
return len(bpy.data.actions) != 0
-
+
def execute(self, context):
removed = 0
-
+
for action in bpy.data.actions:
# if only user is "fake" user...
- if ((self.only_unused is False) or
+ if ((self.only_unused is False) or
(action.use_fake_user and action.users == 1)):
-
- # if it has F-Curves, then it's a "action library" (i.e. walk, wave, jump, etc.)
+
+ # if it has F-Curves, then it's a "action library" (i.e. walk, wave, jump, etc.)
# and should be left alone as that's what fake users are for!
if not action.fcurves:
# mark action for deletion
action.user_clear()
removed += 1
-
+
self.report({'INFO'}, "Removed %d empty and/or fake-user only Actions" % (removed))
return {'FINISHED'}
diff --git a/release/scripts/startup/ui_mocap.py b/release/scripts/startup/ui_mocap.py
index 737f3fcfa56..d750489191f 100644
--- a/release/scripts/startup/ui_mocap.py
+++ b/release/scripts/startup/ui_mocap.py
@@ -80,7 +80,7 @@ class MocapConstraint(bpy.types.PropertyGroup):
baked = bpy.props.BoolProperty(name="Baked / Applied",
default=False,
description="Constraint has been baked to NLA layer",
- update=updateConstraint)
+ update=updateBake)
targetPoint = bpy.props.FloatVectorProperty(name="Point", size=3,
subtype="XYZ", default=(0.0, 0.0, 0.0),
description="Target of Constraint - Point",
@@ -157,11 +157,6 @@ bpy.types.PoseBone.IKRetarget = bpy.props.BoolProperty(name="IK",
update=toggleIKBone, default=False)
-def hasIKConstraint(pose_bone):
- #utility function / predicate, returns True if given bone has IK constraint
- return ("IK" in [constraint.type for constraint in pose_bone.constraints])
-
-
def updateIKRetarget():
# ensures that Blender constraints and IK properties are in sync
# currently runs when module is loaded, should run when scene is loaded
@@ -230,8 +225,6 @@ class MocapPanel(bpy.types.Panel):
else:
row.label(" ")
row.label(" ")
-
-
self.layout.operator("mocap.retarget", text='RETARGET!')
@@ -328,6 +321,7 @@ class OBJECT_OT_LimitDOFButton(bpy.types.Operator):
def execute(self, context):
return {"FINISHED"}
+
class OBJECT_OT_RotateFixArmature(bpy.types.Operator):
bl_idname = "mocap.rotate_fix"
bl_label = "Rotates selected armature 90 degrees (fix for bvh import)"
@@ -335,7 +329,7 @@ class OBJECT_OT_RotateFixArmature(bpy.types.Operator):
def execute(self, context):
mocap_tools.rotate_fix_armature(context.active_object.data)
return {"FINISHED"}
-
+
#def poll(self, context):
# return context.active_object.data in bpy.data.armatures