[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2259] trunk/py/scripts/addons: committing Motion Capture Add-on - Final deliverable for GSoC project 2011

Brendon Murphy meta.androcto1 at gmail.com
Wed Aug 24 13:46:00 CEST 2011


Revision: 2259
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2259
Author:   meta-androcto
Date:     2011-08-24 11:45:59 +0000 (Wed, 24 Aug 2011)
Log Message:
-----------
committing Motion Capture Add-on - Final deliverable for GSoC project 2011
thanks to Benjy Cook
well done!

Added Paths:
-----------
    trunk/py/scripts/addons/mocap/
    trunk/py/scripts/addons/mocap/__init__.py
    trunk/py/scripts/addons/mocap/mocap_constraints.py
    trunk/py/scripts/addons/mocap/mocap_tools.py
    trunk/py/scripts/addons/mocap/retarget.py

Added: trunk/py/scripts/addons/mocap/__init__.py
===================================================================
--- trunk/py/scripts/addons/mocap/__init__.py	                        (rev 0)
+++ trunk/py/scripts/addons/mocap/__init__.py	2011-08-24 11:45:59 UTC (rev 2259)
@@ -0,0 +1,886 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+    "name": "Motion Capture Tools",
+    "author": "Benjy Cook",
+    "blender": (2, 5, 9),
+    "api": 39523,
+    "location": "Object UI -> Mocap tools",
+    "description": "Various tools for working with motion capture animation",
+    "warning": "",
+    "wiki_url": ("http://wiki.blender.org/index.php/User:Benjycook/GSOC/Manual"),
+    "tracker_url": "",
+    "support": 'OFFICIAL',
+    "category": "Animation"}
+
+if "bpy" in locals():
+    import imp
+    if "mocap_constraints" in locals():
+        imp.reload(mocap_constraints)
+    if "retarget" in locals():
+        imp.reload(retarget)
+    if "mocap_tools" in locals():
+        imp.reload(mocap_tools)
+else:
+    import bpy
+    from bpy.props import *
+    from bpy import *
+    from . import mocap_constraints
+    from . import retarget
+    from . import mocap_tools
+    from .mocap_constraints import *
+
+# MocapConstraint class
+# Defines MocapConstraint datatype, used to add and configute mocap constraints
+# Attached to Armature data
+
+
+class MocapConstraint(bpy.types.PropertyGroup):
+    name = bpy.props.StringProperty(name="Name",
+        default="Mocap Fix",
+        description="Name of Mocap Fix",
+        update=setConstraint)
+    constrained_bone = bpy.props.StringProperty(name="Bone",
+        default="",
+        description="Constrained Bone",
+        update=updateConstraintBoneType)
+    constrained_boneB = bpy.props.StringProperty(name="Bone (2)",
+        default="",
+        description="Other Constrained Bone (optional, depends on type)",
+        update=setConstraint)
+    s_frame = bpy.props.IntProperty(name="S",
+        default=0,
+        description="Start frame of Fix",
+        update=setConstraint)
+    e_frame = bpy.props.IntProperty(name="E",
+        default=100,
+        description="End frame of Fix",
+        update=setConstraint)
+    smooth_in = bpy.props.IntProperty(name="In",
+        default=10,
+        description="Amount of frames to smooth in",
+        update=setConstraint,
+        min=0)
+    smooth_out = bpy.props.IntProperty(name="Out",
+        default=10,
+        description="Amount of frames to smooth out",
+        update=setConstraint,
+        min=0)
+    targetMesh = bpy.props.StringProperty(name="Mesh",
+        default="",
+        description="Target of Fix - Mesh (optional, depends on type)",
+        update=setConstraint)
+    active = bpy.props.BoolProperty(name="Active",
+        default=True,
+        description="Fix is active",
+        update=setConstraint)
+    show_expanded = bpy.props.BoolProperty(name="Show Expanded",
+        default=True,
+        description="Fix is fully shown")
+    targetPoint = bpy.props.FloatVectorProperty(name="Point", size=3,
+        subtype="XYZ", default=(0.0, 0.0, 0.0),
+        description="Target of Fix - Point",
+        update=setConstraint)
+    targetDist = bpy.props.FloatProperty(name="Offset",
+        default=0.0,
+        description="Distance and Floor Fixes - Desired offset",
+        update=setConstraint)
+    targetSpace = bpy.props.EnumProperty(
+        items=[("WORLD", "World Space", "Evaluate target in global space"),
+            ("LOCAL", "Object space", "Evaluate target in object space"),
+            ("constrained_boneB", "Other Bone Space", "Evaluate target in specified other bone space")],
+        name="Space",
+        description="In which space should Point type target be evaluated",
+        update=setConstraint)
+    type = bpy.props.EnumProperty(name="Type of constraint",
+        items=[("point", "Maintain Position", "Bone is at a specific point"),
+            ("freeze", "Maintain Position at frame", "Bone does not move from location specified in target frame"),
+            ("floor", "Stay above", "Bone does not cross specified mesh object eg floor"),
+            ("distance", "Maintain distance", "Target bones maintained specified distance")],
+        description="Type of Fix",
+        update=updateConstraintBoneType)
+    real_constraint = bpy.props.StringProperty()
+    real_constraint_bone = bpy.props.StringProperty()
+
+
+
+# Animation Stitch Settings, used for animation stitching of 2 retargeted animations.
+class AnimationStitchSettings(bpy.types.PropertyGroup):
+    first_action = bpy.props.StringProperty(name="Action 1",
+            description="First action in stitch")
+    second_action = bpy.props.StringProperty(name="Action 2",
+            description="Second action in stitch")
+    blend_frame = bpy.props.IntProperty(name="Stitch frame",
+            description="Frame to locate stitch on")
+    blend_amount = bpy.props.IntProperty(name="Blend amount",
+            description="Size of blending transitiion, on both sides of the stitch",
+            default=10)
+    second_offset = bpy.props.IntProperty(name="Second offset",
+            description="Frame offset for 2nd animation, where it should start",
+            default=10)
+    stick_bone = bpy.props.StringProperty(name="Stick Bone",
+            description="Bone to freeze during transition",
+            default="")
+
+
+
+# MocapNLA Tracks. Stores which tracks/actions are associated with each retargeted animation.
+class MocapNLATracks(bpy.types.PropertyGroup):
+    name = bpy.props.StringProperty()
+    base_track = bpy.props.StringProperty()
+    auto_fix_track = bpy.props.StringProperty()
+    manual_fix_track = bpy.props.StringProperty()
+    stride_action = bpy.props.StringProperty()
+
+
+
+
+#Update function for Advanced Retarget boolean variable.
+def advancedRetargetToggle(self, context):
+    enduser_obj = context.active_object
+    performer_obj = [obj for obj in context.selected_objects if obj != enduser_obj]
+    if enduser_obj is None or len(performer_obj) != 1:
+        print("Need active and selected armatures")
+        return
+    else:
+        performer_obj = performer_obj[0]
+    if self.advancedRetarget:
+        retarget.preAdvancedRetargeting(performer_obj, enduser_obj)
+    else:
+        retarget.cleanTempConstraints(enduser_obj)
+
+
+
+def toggleIKBone(self, context):
+    #Update function for IK functionality. Is called when IK prop checkboxes are toggled.
+    if self.IKRetarget:
+        if not self.is_in_ik_chain:
+            print(self.name + " IK toggled ON!")
+            ik = self.constraints.new('IK')
+            #ik the whole chain up to the root, excluding
+            chainLen = 0
+            for parent_bone in self.parent_recursive:
+                chainLen += 1
+                if hasIKConstraint(parent_bone):
+                    break
+                deformer_children = [child for child in parent_bone.children if child.bone.use_deform]
+                #~ if len(deformer_children) > 1:
+                    #~ break
+            ik.chain_count = chainLen
+            for bone in self.parent_recursive:
+                if bone.is_in_ik_chain:
+                    bone.IKRetarget = True
+    else:
+        print(self.name + " IK toggled OFF!")
+        cnstrn_bones = []
+        newChainLength = []
+        if hasIKConstraint(self):
+            cnstrn_bones = [self]
+        elif self.is_in_ik_chain:
+            cnstrn_bones = [child for child in self.children_recursive if hasIKConstraint(child)]
+            for cnstrn_bone in cnstrn_bones:
+                newChainLength.append(cnstrn_bone.parent_recursive.index(self) + 1)
+        if cnstrn_bones:
+            # remove constraint, and update IK retarget for all parents of cnstrn_bone up to chain_len
+            for i, cnstrn_bone in enumerate(cnstrn_bones):
+                print(cnstrn_bone.name)
+                if newChainLength:
+                    ik = hasIKConstraint(cnstrn_bone)
+                    ik.chain_count = newChainLength[i]
+                else:
+                    ik = hasIKConstraint(cnstrn_bone)
+                    cnstrn_bone.constraints.remove(ik)
+                    cnstrn_bone.IKRetarget = False
+            for bone in cnstrn_bone.parent_recursive:
+                if not bone.is_in_ik_chain:
+                    bone.IKRetarget = False
+
+
+#MocapMap class for storing mapping on enduser performer,
+# where a bone may be linked to more than one on the performer
+class MocapMapping(bpy.types.PropertyGroup):
+    name = bpy.props.StringProperty()
+
+
+
+def updateIKRetarget():
+    # ensures that Blender constraints and IK properties are in sync
+    # currently runs when module is loaded, should run when scene is loaded
+    # or user adds a constraint to armature. Will be corrected in the future,
+    # once python callbacks are implemented
+    for obj in bpy.data.objects:
+        if obj.pose:
+            bones = obj.pose.bones
+            for pose_bone in bones:
+                if pose_bone.is_in_ik_chain or hasIKConstraint(pose_bone):
+                    pose_bone.IKRetarget = True
+                else:
+                    pose_bone.IKRetarget = False
+
+updateIKRetarget()
+
+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
+
+class MocapPanel(bpy.types.Panel):
+    # Motion capture retargeting panel
+    bl_label = "Mocap tools"

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list