[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