[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38548] branches/soc-2011-pepper/release/ scripts: Two new operators for easier retargeting: Auto scale performer, and a first attempt at auto hiearchy mapping

Benjy Cook benjycook at hotmail.com
Wed Jul 20 23:03:06 CEST 2011


Revision: 38548
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38548
Author:   benjycook
Date:     2011-07-20 21:03:06 +0000 (Wed, 20 Jul 2011)
Log Message:
-----------
Two new operators for easier retargeting: Auto scale performer, and a first attempt at auto hiearchy mapping

Modified Paths:
--------------
    branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py
    branches/soc-2011-pepper/release/scripts/modules/retarget.py
    branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py

Modified: branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py	2011-07-20 20:34:40 UTC (rev 38547)
+++ branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py	2011-07-20 21:03:06 UTC (rev 38548)
@@ -573,7 +573,67 @@
         perf_bones = performer_obj.data.bones
         end_bones = enduser_obj.data.bones
 
-       #perf_avg = performer_obj.dimensions
+        def calculateBoundingRadius(bones):
+            center = Vector()
+            for bone in bones:
+                center += bone.head_local
+            center /= len(bones)
+            radius = 0
+            for bone in bones:
+                dist = (bone.head_local - center).length
+                if dist > radius:
+                    radius = dist
+            return radius
+
+        perf_rad = calculateBoundingRadius(performer_obj.data.bones)
+        end_rad = calculateBoundingRadius(enduser_obj.data.bones)
         #end_avg = enduser_obj.dimensions
-        #print(perf_avg, end_avg)
-        #performer_obj.scale /= (perf_avg / end_avg)
+        factor = end_rad / perf_rad * 1.2
+        performer_obj.scale *= factor
+
+
+def guessMapping(performer_obj, enduser_obj):
+        perf_bones = performer_obj.data.bones
+        end_bones = enduser_obj.data.bones
+
+        root = perf_bones[0]
+
+        def findBoneSide(bone):
+            if "Left" in bone:
+                return "Left", bone.replace("Left", "").lower().replace(".", "")
+            if "Right" in bone:
+                return "Right", bone.replace("Right", "").lower().replace(".", "")
+            if "L" in bone:
+                return "Left", bone.replace("Left", "").lower().replace(".", "")
+            if "R" in bone:
+                return "Right", bone.replace("Right", "").lower().replace(".", "")
+            return "", bone
+
+        def nameMatch(bone_a, bone_b):
+            # nameMatch - recieves two strings, returns 2 if they are relatively the same, 1 if they are the same but R and L and 0 if no match at all
+            side_a, noside_a = findBoneSide(bone_a)
+            side_b, noside_b = findBoneSide(bone_b)
+            if side_a == side_b:
+                if noside_a in noside_b or noside_b in noside_a:
+                    return 2
+            else:
+                if noside_a in noside_b or noside_b in noside_a:
+                    return 1
+            return 0
+
+        def guessSingleMapping(perf_bone):
+            possible_bones = [end_bones[0]]
+            while possible_bones:
+                for end_bone in possible_bones:
+                    match = nameMatch(perf_bone.name, end_bone.name)
+                    if match == 2 and not perf_bone.map:
+                        perf_bone.map = end_bone.name
+                newPossibleBones = []
+                for end_bone in possible_bones:
+                    newPossibleBones += list(end_bone.children)
+                possible_bones = newPossibleBones
+
+            for child in perf_bone.children:
+                guessSingleMapping(child)
+
+        guessSingleMapping(root)

Modified: branches/soc-2011-pepper/release/scripts/modules/retarget.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/modules/retarget.py	2011-07-20 20:34:40 UTC (rev 38547)
+++ branches/soc-2011-pepper/release/scripts/modules/retarget.py	2011-07-20 21:03:06 UTC (rev 38548)
@@ -143,7 +143,7 @@
 
     for t in range(s_frame, e_frame):
         if (t - s_frame) % 10 == 0:
-            print("First pass: retargeting frame {0}/{1}".format(t, e_frame - s_frame))      
+            print("First pass: retargeting frame {0}/{1}".format(t, e_frame - s_frame))
         scene.frame_set(t)
         for bone in inter_bones:
             retargetPerfToInter(bone)
@@ -202,7 +202,7 @@
 
     for t in range(s_frame, e_frame):
         if (t - s_frame) % 10 == 0:
-            print("Second pass: retargeting frame {0}/{1}".format(t, e_frame - s_frame))   
+            print("Second pass: retargeting frame {0}/{1}".format(t, e_frame - s_frame))
         scene.frame_set(t)
         end_bone = end_bones[root]
         end_bone.location = Vector((0, 0, 0))

Modified: branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py	2011-07-20 20:34:40 UTC (rev 38547)
+++ branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py	2011-07-20 21:03:06 UTC (rev 38548)
@@ -196,16 +196,17 @@
         row2.operator("mocap.looper", text='Loop animation')
         row2.operator("mocap.limitdof", text='Constrain Rig')
         self.layout.label("Retargeting")
-        row3 = self.layout.row(align=True)
-        column1 = row3.column(align=True)
-        column1.label("Performer Rig")
-        column2 = row3.column(align=True)
-        column2.label("Enduser Rig")
         enduser_obj = bpy.context.active_object
         performer_obj = [obj for obj in bpy.context.selected_objects if obj != enduser_obj]
         if enduser_obj is None or len(performer_obj) != 1:
             self.layout.label("Select performer rig and target rig (as active)")
         else:
+            self.layout.operator("mocap.guessmapping", text="Guess Hiearchy Mapping")
+            row3 = self.layout.row(align=True)
+            column1 = row3.column(align=True)
+            column1.label("Performer Rig")
+            column2 = row3.column(align=True)
+            column2.label("Enduser Rig")
             performer_obj = performer_obj[0]
             if performer_obj.data and enduser_obj.data:
                 if performer_obj.data.name in bpy.data.armatures and enduser_obj.data.name in bpy.data.armatures:
@@ -532,6 +533,28 @@
             return isinstance(context.active_object.data, bpy.types.Armature)
 
 
+class OBJECT_OT_GuessHierachyMapping(bpy.types.Operator):
+    '''Attemps to auto figure out hierarchy mapping'''
+    bl_idname = "mocap.guessmapping"
+    bl_label = "Attemps to auto figure out hierarchy mapping"
+
+    def execute(self, context):
+        enduser_obj = bpy.context.active_object
+        performer_obj = [obj for obj in bpy.context.selected_objects if obj != enduser_obj][0]
+        mocap_tools.guessMapping(performer_obj, enduser_obj)
+        return {"FINISHED"}
+
+    @classmethod
+    def poll(cls, context):
+        if context.active_object:
+            activeIsArmature = isinstance(context.active_object.data, bpy.types.Armature)
+        performer_obj = [obj for obj in context.selected_objects if obj != context.active_object]
+        if performer_obj:
+            return activeIsArmature and isinstance(performer_obj[0].data, bpy.types.Armature)
+        else:
+            return False
+
+
 def register():
     bpy.utils.register_module(__name__)
 




More information about the Bf-blender-cvs mailing list