diff options
author | Thomas Larsson <thomas_larsson_01@hotmail.com> | 2011-09-21 18:24:19 +0400 |
---|---|---|
committer | Thomas Larsson <thomas_larsson_01@hotmail.com> | 2011-09-21 18:24:19 +0400 |
commit | a02c5228a0ad48d2b06cde2dddcaa52523d5313f (patch) | |
tree | 51177c2d3c687ce0ae52e2df6b097c3a759da649 /io_import_scene_mhx.py | |
parent | e7917861175a3aed08ed00cd490df81f9a6fe56d (diff) |
MHX importer v1.8. Pose tools merged with importer.
Diffstat (limited to 'io_import_scene_mhx.py')
-rw-r--r-- | io_import_scene_mhx.py | 870 |
1 files changed, 721 insertions, 149 deletions
diff --git a/io_import_scene_mhx.py b/io_import_scene_mhx.py index 229572c7..4633d83c 100644 --- a/io_import_scene_mhx.py +++ b/io_import_scene_mhx.py @@ -26,7 +26,7 @@ """ Abstract MHX (MakeHuman eXchange format) importer for Blender 2.5x. -Version 1.7.1 +Version 1.8.0 This script should be distributed with Blender. If not, place it in the .blender/scripts/addons dir @@ -39,9 +39,9 @@ Alternatively, run the script in the script editor (Alt-P), and access from the bl_info = { 'name': 'Import: MakeHuman (.mhx)', 'author': 'Thomas Larsson', - 'version': (1, 7, 1), - "blender": (2, 5, 8), - "api": 37702, + 'version': (1, 8, 0), + "blender": (2, 5, 9), + "api": 40335, 'location': "File > Import > MakeHuman (.mhx)", 'description': 'Import files in the MakeHuman eXchange format (.mhx)', 'warning': '', @@ -51,9 +51,9 @@ bl_info = { 'category': 'Import-Export'} MAJOR_VERSION = 1 -MINOR_VERSION = 7 -SUB_VERSION = 1 -BLENDER_VERSION = (2, 58, 0) +MINOR_VERSION = 8 +SUB_VERSION = 0 +BLENDER_VERSION = (2, 59, 2) # # @@ -62,9 +62,8 @@ BLENDER_VERSION = (2, 58, 0) import bpy import os import time -from mathutils import Matrix -#import geometry -#import string +import mathutils +from bpy.props import * MHX249 = False Blender24 = False @@ -2089,144 +2088,7 @@ def deleteDiamonds(ob): bpy.ops.mesh.delete(type='VERT') bpy.ops.object.mode_set(mode='OBJECT') return - - -# -# parseProcess(args, tokens): -# applyTransform(objects, rig, parents): -# - -def parseProcess(args, tokens): - return - """ - if toggle & T_Bend == 0: - return - try: - rig = loadedData['Object'][args[0]] - except: - rig = None - if not rig: - return - - parents = {} - objects = [] - - for (key, val, sub) in tokens: - #print(key, val) - if key == 'Reparent': - bname = val[0] - try: - eb = ebones[bname] - parents[bname] = eb.parent.name - eb.parent = ebones[val[1]] - except: - pass - elif key == 'Bend': - axis = val[1] - angle = float(val[2]) - mat = Matrix.Rotation(angle, 4, axis) - try: - pb = pbones[val[0]] - except: - pb = None - print("No bone "+val[0]) - if pb: - prod = pb.matrix_basis * mat - for i in range(4): - for j in range(4): - pb.matrix_basis[i][j] = prod[i][j] - elif key == 'Snap': - try: - eb = ebones[val[0]] - except: - eb = None - tb = ebones[val[1]] - typ = val[2] - if eb is None: - pass - elif typ == 'Inv': - eb.head = tb.tail - eb.tail = tb.head - elif typ == 'Head': - eb.head = tb.head - elif typ == 'Tail': - eb.tail = tb.tail - elif typ == 'Both': - eb.head = tb.head - eb.tail = tb.tail - eb.roll = tb.roll - else: - MyError("Snap type %s" % typ) - elif key == 'PoseMode': - bpy.context.scene.objects.active = rig - bpy.ops.object.mode_set(mode='POSE') - pbones = rig.pose.bones - elif key == 'ObjectMode': - bpy.context.scene.objects.active = rig - bpy.ops.object.mode_set(mode='POSE') - pbones = rig.pose.bones - elif key == 'EditMode': - bpy.context.scene.objects.active = rig - bpy.ops.object.mode_set(mode='EDIT') - ebones = rig.data.edit_bones - bpy.ops.armature.select_all(action='DESELECT') - elif key == 'Roll': - try: - eb = ebones[val[0]] - except: - eb = None - if eb: - eb.roll = float(val[1]) - elif key == 'Select': - pass - elif key == 'RollUp': - pass - elif key == 'Apply': - applyTransform(objects, rig, parents) - elif key == 'ApplyArmature': - try: - ob = loadedData['Object'][val[0]] - objects.append((ob,sub)) - except: - ob = None - elif key == 'Object': - try: - ob = loadedData['Object'][val[0]] - except: - ob = None - if ob: - bpy.context.scene.objects.active = ob - #mod = ob.modifiers[0] - #ob.modifiers.remove(mod) - for (key1, val1, sub1) in sub: - if key1 == 'Modifier': - parseModifier(ob, val1, sub1) - return - -def applyTransform(objects, rig, parents): - for (ob,tokens) in objects: - print("Applying transform to %s" % ob) - bpy.context.scene.objects.active = ob - bpy.ops.object.visual_transform_apply() - bpy.ops.object.modifier_apply(apply_as='DATA', modifier='Armature') - - bpy.context.scene.objects.active = rig - bpy.ops.object.mode_set(mode='POSE') - bpy.ops.pose.armature_apply() - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.mode_set(mode='EDIT') - ebones = rig.data.edit_bones - for (bname, pname) in parents.items(): - eb = ebones[bname] - par = ebones[pname] - if eb.use_connect: - par.tail = eb.head - eb.parent = par - - bpy.ops.object.mode_set(mode='OBJECT') - return - """ - + # # defaultKey(ext, args, tokens, var, exclude, glbals, lcals): # @@ -2400,7 +2262,7 @@ def parseBoolArray(mask): # def parseMatrix(args, tokens): - matrix = Matrix() + matrix = mathutils.Matrix() i = 0 for (key, val, sub) in tokens: if key == 'row': @@ -3065,6 +2927,716 @@ class ImportMhx(bpy.types.Operator, ImportHelper): context.window_manager.fileselect_add(self) return {'RUNNING_MODAL'} + +################################################################################### +# +# Lipsync panel +# +################################################################################### + +# +# visemes +# + +stopStaringVisemes = ({ + 'Rest' : [ + ('PMouth', (0,0)), + ('PUpLip', (0,-0.1)), + ('PLoLip', (0,0.1)), + ('PJaw', (0,0.05)), + ('PTongue', (0,0.0))], + 'Etc' : [ + ('PMouth', (0,0)), + ('PUpLip', (0,-0.1)), + ('PLoLip', (0,0.1)), + ('PJaw', (0,0.15)), + ('PTongue', (0,0.0))], + 'MBP' : [('PMouth', (-0.3,0)), + ('PUpLip', (0,1)), + ('PLoLip', (0,0)), + ('PJaw', (0,0.1)), + ('PTongue', (0,0.0))], + 'OO' : [('PMouth', (-1.5,0)), + ('PUpLip', (0,0)), + ('PLoLip', (0,0)), + ('PJaw', (0,0.2)), + ('PTongue', (0,0.0))], + 'O' : [('PMouth', (-1.1,0)), + ('PUpLip', (0,0)), + ('PLoLip', (0,0)), + ('PJaw', (0,0.5)), + ('PTongue', (0,0.0))], + 'R' : [('PMouth', (-0.9,0)), + ('PUpLip', (0,-0.2)), + ('PLoLip', (0,0.2)), + ('PJaw', (0,0.2)), + ('PTongue', (0,0.0))], + 'FV' : [('PMouth', (0,0)), + ('PUpLip', (0,0)), + ('PLoLip', (0,-0.8)), + ('PJaw', (0,0.1)), + ('PTongue', (0,0.0))], + 'S' : [('PMouth', (0,0)), + ('PUpLip', (0,-0.2)), + ('PLoLip', (0,0.2)), + ('PJaw', (0,0.05)), + ('PTongue', (0,0.0))], + 'SH' : [('PMouth', (-0.6,0)), + ('PUpLip', (0,-0.5)), + ('PLoLip', (0,0.5)), + ('PJaw', (0,0)), + ('PTongue', (0,0.0))], + 'EE' : [('PMouth', (0.3,0)), + ('PUpLip', (0,-0.3)), + ('PLoLip', (0,0.3)), + ('PJaw', (0,0.025)), + ('PTongue', (0,0.0))], + 'AH' : [('PMouth', (-0.1,0)), + ('PUpLip', (0,-0.4)), + ('PLoLip', (0,0)), + ('PJaw', (0,0.35)), + ('PTongue', (0,0.0))], + 'EH' : [('PMouth', (0.1,0)), + ('PUpLip', (0,-0.2)), + ('PLoLip', (0,0.2)), + ('PJaw', (0,0.2)), + ('PTongue', (0,0.0))], + 'TH' : [('PMouth', (0,0)), + ('PUpLip', (0,-0.5)), + ('PLoLip', (0,0.5)), + ('PJaw', (-0.2,0.1)), + ('PTongue', (0,-0.6))], + 'L' : [('PMouth', (0,0)), + ('PUpLip', (0,-0.2)), + ('PLoLip', (0,0.2)), + ('PJaw', (0.2,0.2)), + ('PTongue', (0,-0.8))], + 'G' : [('PMouth', (0,0)), + ('PUpLip', (0,-0.1)), + ('PLoLip', (0,0.1)), + ('PJaw', (-0.3,0.1)), + ('PTongue', (0,-0.6))], + + 'Blink' : [('PUpLid', (0,1.0)), ('PLoLid', (0,-1.0))], + 'Unblink' : [('PUpLid', (0,0)), ('PLoLid', (0,0))], +}) + +bodyLanguageVisemes = ({ + 'Rest' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,-0.6)), + ('PUpLipMid', (0,0)), + ('PLoLipMid', (0,0)), + ('PJaw', (0,0)), + ('PTongue', (0,0))], + 'Etc' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,-0.4)), + ('PUpLipMid', (0,0)), + ('PLoLipMid', (0,0)), + ('PJaw', (0,0)), + ('PTongue', (0,0))], + 'MBP' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,0)), + ('PLoLipMid', (0,0)), + ('PJaw', (0,0)), + ('PTongue', (0,0))], + 'OO' : [ + ('PMouth', (-1.0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,0)), + ('PLoLipMid', (0,0)), + ('PJaw', (0,0.4)), + ('PTongue', (0,0))], + 'O' : [ + ('PMouth', (-0.9,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,0)), + ('PLoLipMid', (0,0)), + ('PJaw', (0,0.8)), + ('PTongue', (0,0))], + 'R' : [ + ('PMouth', (-0.5,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-0.2)), + ('PLoLipMid', (0,0.2)), + ('PJaw', (0,0)), + ('PTongue', (0,0))], + 'FV' : [ + ('PMouth', (-0.2,0)), + ('PMouthMid', (0,1.0)), + ('PUpLipMid', (0,0)), + ('PLoLipMid', (-0.6,-0.3)), + ('PJaw', (0,0)), + ('PTongue', (0,0))], + 'S' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-0.5)), + ('PLoLipMid', (0,0.7)), + ('PJaw', (0,0)), + ('PTongue', (0,0))], + 'SH' : [ + ('PMouth', (-0.8,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-1.0)), + ('PLoLipMid', (0,1.0)), + ('PJaw', (0,0)), + ('PTongue', (0,0))], + 'EE' : [ + ('PMouth', (0.2,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-0.6)), + ('PLoLipMid', (0,0.6)), + ('PJaw', (0,0.05)), + ('PTongue', (0,0))], + 'AH' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-0.4)), + ('PLoLipMid', (0,0)), + ('PJaw', (0,0.7)), + ('PTongue', (0,0))], + 'EH' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-0.5)), + ('PLoLipMid', (0,0.6)), + ('PJaw', (0,0.25)), + ('PTongue', (0,0))], + 'TH' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,0)), + ('PLoLipMid', (0,0)), + ('PJaw', (0,0.2)), + ('PTongue', (1.0,1.0))], + 'L' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-0.5)), + ('PLoLipMid', (0,0.5)), + ('PJaw', (0,-0.2)), + ('PTongue', (1.0,1.0))], + 'G' : [ + ('PMouth', (0,0)), + ('PMouthMid', (0,0)), + ('PUpLipMid', (0,-0.5)), + ('PLoLipMid', (0,0.5)), + ('PJaw', (0,-0.2)), + ('PTongue', (-1.0,0))], + + 'Blink' : [('PUpLid', (0,1.0)), ('PLoLid', (0,-1.0))], + 'Unblink' : [('PUpLid', (0,0)), ('PLoLid', (0,0))], +}) + +VisemeList = [ + ('Rest', 'Etc', 'AH'), + ('MBP', 'OO', 'O'), + ('R', 'FV', 'S'), + ('SH', 'EE', 'EH'), + ('TH', 'L', 'G') +] + +# +# mohoVisemes +# magpieVisemes +# + +mohoVisemes = dict({ + 'rest' : 'Rest', + 'etc' : 'Etc', + 'AI' : 'AH', + 'O' : 'O', + 'U' : 'OO', + 'WQ' : 'AH', + 'L' : 'L', + 'E' : 'EH', + 'MBP' : 'MBP', + 'FV' : 'FV', +}) + +magpieVisemes = dict({ + "CONS" : "t,d,k,g,T,D,s,z,S,Z,h,n,N,j,r,tS", + "AI" : "i,&,V,aU,I,0,@,aI", + "E" : "eI,3,e", + "O" : "O,@U,oI", + "UW" : "U,u,w", + "MBP" : "m,b,p", + "L" : "l", + "FV" : "f,v", + "Sh" : "dZ", +}) + +# +# setViseme(context, vis, setKey, frame): +# setBoneLocation(context, pbone, loc, mirror, setKey, frame): +# class VIEW3D_OT_MhxVisemeButton(bpy.types.Operator): +# + +def getVisemeSet(context, rig): + try: + visset = rig['MhxVisemeSet'] + except: + return bodyLanguageVisemes + if visset == 'StopStaring': + return stopStaringVisemes + elif visset == 'BodyLanguage': + return bodyLanguageVisemes + else: + raise NameError("Unknown viseme set %s" % visset) + +def setViseme(context, vis, setKey, frame): + rig = getMhxRig(context.object) + pbones = rig.pose.bones + try: + scale = pbones['PFace'].bone.length + except: + return + visemes = getVisemeSet(context, rig) + for (b, (x, z)) in visemes[vis]: + loc = mathutils.Vector((float(x),0,float(z))) + try: + pb = pbones[b] + except: + + pb = None + + if pb: + setBoneLocation(context, pb, scale, loc, False, setKey, frame) + else: + setBoneLocation(context, pbones[b+'_L'], scale, loc, False, setKey, frame) + setBoneLocation(context, pbones[b+'_R'], scale, loc, True, setKey, frame) + return + +def setBoneLocation(context, pb, scale, loc, mirror, setKey, frame): + if mirror: + loc[0] = -loc[0] + pb.location = loc*scale*0.2 + + if setKey or context.tool_settings.use_keyframe_insert_auto: + for n in range(3): + pb.keyframe_insert('location', index=n, frame=frame, group=pb.name) + return + +class VIEW3D_OT_MhxVisemeButton(bpy.types.Operator): + bl_idname = 'mhx.pose_viseme' + bl_label = 'Viseme' + viseme = StringProperty() + + def invoke(self, context, event): + setViseme(context, self.viseme, False, context.scene.frame_current) + return{'FINISHED'} + + + +# +# openFile(context, filepath): +# readMoho(context, filepath, offs): +# readMagpie(context, filepath, offs): +# + +def openFile(context, filepath): + (path, fileName) = os.path.split(filepath) + (name, ext) = os.path.splitext(fileName) + return open(filepath, "rU") + +def readMoho(context, filepath, offs): + rig = getMhxRig(context.object) + context.scene.objects.active = rig + bpy.ops.object.mode_set(mode='POSE') + fp = openFile(context, filepath) + for line in fp: + words= line.split() + if len(words) < 2: + pass + else: + vis = mohoVisemes[words[1]] + setViseme(context, vis, True, int(words[0])+offs) + fp.close() + setInterpolation(context.object) + print("Moho file %s loaded" % filepath) + return + +def readMagpie(context, filepath, offs): + rig = getMhxRig(context.object) + context.scene.objects.active = rig + bpy.ops.object.mode_set(mode='POSE') + fp = openFile(context, filepath) + for line in fp: + words= line.split() + if len(words) < 3: + pass + elif words[2] == 'X': + vis = magpieVisemes[words[3]] + setViseme(context, vis, True, int(words[0])+offs) + fp.close() + setInterpolation(context.object) + print("Magpie file %s loaded" % filepath) + return + +# +# class VIEW3D_OT_MhxLoadMohoButton(bpy.types.Operator): +# + +class VIEW3D_OT_MhxLoadMohoButton(bpy.types.Operator): + bl_idname = "mhx.pose_load_moho" + bl_label = "Moho (.dat)" + filepath = StringProperty(name="File Path", description="File path used for importing the file", maxlen= 1024, default= "") + startFrame = IntProperty(name="Start frame", description="First frame to import", default=1) + + def execute(self, context): + import bpy, os, mathutils + readMoho(context, self.properties.filepath, self.properties.startFrame-1) + return{'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + +# +# class VIEW3D_OT_MhxLoadMagpieButton(bpy.types.Operator): +# + +class VIEW3D_OT_MhxLoadMagpieButton(bpy.types.Operator): + bl_idname = "mhx.pose_load_magpie" + bl_label = "Magpie (.mag)" + filepath = StringProperty(name="File Path", description="File path used for importing the file", maxlen= 1024, default= "") + startFrame = IntProperty(name="Start frame", description="First frame to import", default=1) + + def execute(self, context): + import bpy, os, mathutils + readMagpie(context, self.properties.filepath, self.properties.startFrame-1) + return{'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + +# +# class MhxLipsyncPanel(bpy.types.Panel): +# + +class MhxLipsyncPanel(bpy.types.Panel): + bl_label = "MHX Lipsync" + bl_space_type = "VIEW_3D" + bl_region_type = "UI" + + @classmethod + def poll(cls, context): + return context.object + + def draw(self, context): + rig = getMhxRig(context.object) + if not rig: + return + + layout = self.layout + layout.label(text="Visemes") + for (vis1, vis2, vis3) in VisemeList: + row = layout.row() + row.operator("mhx.pose_viseme", text=vis1).viseme = vis1 + row.operator("mhx.pose_viseme", text=vis2).viseme = vis2 + row.operator("mhx.pose_viseme", text=vis3).viseme = vis3 + layout.separator() + row = layout.row() + row.operator("mhx.pose_viseme", text="Blink").viseme = 'Blink' + row.operator("mhx.pose_viseme", text="Unblink").viseme = 'Unblink' + layout.label(text="Load file") + row = layout.row() + row.operator("mhx.pose_load_moho") + row.operator("mhx.pose_load_magpie") + return + +################################################################################### +# +# Expression panel +# +################################################################################### +# +# class VIEW3D_OT_MhxResetExpressionsButton(bpy.types.Operator): +# + +class VIEW3D_OT_MhxResetExpressionsButton(bpy.types.Operator): + bl_idname = "mhx.pose_reset_expressions" + bl_label = "Reset expressions" + + def execute(self, context): + rig = getMhxRig(context.object) + props = getShapeProps(rig) + for (prop, name) in props: + rig[prop] = 0.0 + rig.update_tag() + return{'FINISHED'} + +# +# class VIEW3D_OT_MhxKeyExpressionButton(bpy.types.Operator): +# + +class VIEW3D_OT_MhxKeyExpressionsButton(bpy.types.Operator): + bl_idname = "mhx.pose_key_expressions" + bl_label = "Key expressions" + + def execute(self, context): + rig = getMhxRig(context.object) + props = getShapeProps(rig) + frame = context.scene.frame_current + for (prop, name) in props: + rig.keyframe_insert('["%s"]' % prop, frame=frame) + rig.update_tag() + return{'FINISHED'} +# +# class VIEW3D_OT_MhxPinExpressionButton(bpy.types.Operator): +# + +class VIEW3D_OT_MhxPinExpressionButton(bpy.types.Operator): + bl_idname = "mhx.pose_pin_expression" + bl_label = "Pin" + expression = StringProperty() + + def execute(self, context): + rig = getMhxRig(context.object) + props = getShapeProps(rig) + if context.tool_settings.use_keyframe_insert_auto: + frame = context.scene.frame_current + for (prop, name) in props: + old = rig[prop] + if prop == self.expression: + rig[prop] = 1.0 + else: + rig[prop] = 0.0 + if abs(rig[prop] - old) > 1e-3: + rig.keyframe_insert('["%s"]' % prop, frame=frame) + else: + for (prop, name) in props: + if prop == self.expression: + rig[prop] = 1.0 + else: + rig[prop] = 0.0 + rig.update_tag() + return{'FINISHED'} + +# +# getShapeProps(ob): +# + +def getShapeProps(rig): + props = [] + plist = list(rig.keys()) + plist.sort() + for prop in plist: + if prop[0] == '*': + props.append((prop, prop[1:])) + return props + +# +# class MhxExpressionsPanel(bpy.types.Panel): +# + +class MhxExpressionsPanel(bpy.types.Panel): + bl_label = "MHX Expressions" + bl_space_type = "VIEW_3D" + bl_region_type = "UI" + + @classmethod + def poll(cls, context): + return context.object + + def draw(self, context): + rig = getMhxRig(context.object) + if not rig: + return + props = getShapeProps(rig) + if not props: + return + layout = self.layout + layout.label(text="Expressions") + layout.operator("mhx.pose_reset_expressions") + layout.operator("mhx.pose_key_expressions") + layout.separator() + for (prop, name) in props: + row = layout.split(0.75) + row.prop(rig, '["%s"]' % prop, text=name) + row.operator("mhx.pose_pin_expression").expression = prop + return + +################################################################################### +# +# Posing panel +# +################################################################################### +# +# class MhxDriversPanel(bpy.types.Panel): +# + +class MhxDriversPanel(bpy.types.Panel): + bl_label = "MHX Drivers" + bl_space_type = "VIEW_3D" + bl_region_type = "UI" + + @classmethod + def poll(cls, context): + return pollMhxRig(context.object) + + def draw(self, context): + lProps = [] + rProps = [] + props = [] + plist = list(context.object.keys()) + plist.sort() + for prop in plist: + if prop[-2:] == '_L': + lProps.append((prop, prop[:-2])) + elif prop[-2:] == '_R': + rProps.append((prop, prop[:-2])) + elif prop[:3] == 'Mhx' or prop[0] == '_' or prop[0] == '*': + pass + else: + props.append(prop) + ob = context.object + layout = self.layout + for prop in props: + layout.prop(ob, '["%s"]' % prop, text=prop) + layout.label("Left") + for (prop, pname) in lProps: + layout.prop(ob, '["%s"]' % prop, text=pname) + layout.label("Right") + for (prop, pname) in rProps: + layout.prop(ob, '["%s"]' % prop, text=pname) + return + +################################################################################### +# +# Layers panel +# +################################################################################### + +MhxLayers = [ + (( 0, 'Root', 'MhxRoot'), + ( 8, 'Face', 'MhxFace')), + (( 9, 'Tweak', 'MhxTweak'), + (10, 'Head', 'MhxHead')), + (( 1, 'FK Spine', 'MhxFKSpine'), + (17, 'IK Spine', 'MhxIKSpine')), + ((13, 'Inv FK Spine', 'MhxInvFKSpine'), + (29, 'Inv IK Spine', 'MhxInvIKSpine')), + ('Left', 'Right'), + (( 2, 'IK Arm', 'MhxIKArm'), + (18, 'IK Arm', 'MhxIKArm')), + (( 3, 'FK Arm', 'MhxFKArm'), + (19, 'FK Arm', 'MhxFKArm')), + (( 4, 'IK Leg', 'MhxIKLeg'), + (20, 'IK Leg', 'MhxIKLeg')), + (( 5, 'FK Leg', 'MhxFKLeg'), + (21, 'FK Leg', 'MhxFKLeg')), + ((12, 'Tweak', 'MhxTweak'), + (28, 'Tweak', 'MhxTweak')), + (( 6, 'Fingers', 'MhxFingers'), + (22, 'Fingers', 'MhxFingers')), + (( 7, 'Links', 'MhxLinks'), + (23, 'Links', 'MhxLinks')), + ((11, 'Palm', 'MhxPalm'), + (27, 'Palm', 'MhxPalm')), +] + +# +# class MhxLayersPanel(bpy.types.Panel): +# + +class MhxLayersPanel(bpy.types.Panel): + bl_label = "MHX Layers" + bl_space_type = "VIEW_3D" + bl_region_type = "UI" + + @classmethod + def poll(cls, context): + return pollMhxRig(context.object) + + def draw(self, context): + layout = self.layout + layout.operator("mhx.pose_set_all_layers", text='Enable all layers').value = True + layout.operator("mhx.pose_set_all_layers", text='Disable all layers').value = False + amt = context.object.data + for (left,right) in MhxLayers: + row = layout.row() + if type(left) == str: + row.label(left) + row.label(right) + else: + for (n, name, prop) in [left,right]: + row.prop(amt, "layers", index=n, toggle=True, text=name) + return + +class VIEW3D_OT_MhxSetAllLayersButton(bpy.types.Operator): + bl_idname = "mhx.pose_set_all_layers" + bl_label = "Set inverse" + value = BoolProperty() + + def execute(self, context): + rig = getMhxRig(context.object) + for (left,right) in MhxLayers: + if type(left) != str: + for (n, name, prop) in [left,right]: + rig.data.layers[n] = self.value + return{'FINISHED'} + +################################################################################### +# +# Common functions +# +################################################################################### +# +# pollMhxRig(ob): +# getMhxRig(ob): +# + +def pollMhxRig(ob): + try: + return (ob["MhxRig"] == "MHX") + except: + return False + +def getMhxRig(ob): + if ob.type == 'ARMATURE': + rig = ob + elif ob.type == 'MESH': + rig = ob.parent + else: + return None + try: + if (rig["MhxRig"] == "MHX"): + return rig + else: + return None + except: + return None + + +# +# setInterpolation(rig): +# + +def setInterpolation(rig): + if not rig.animation_data: + return + act = rig.animation_data.action + if not act: + return + for fcu in act.fcurves: + for pt in fcu.keyframe_points: + pt.interpolation = 'LINEAR' + fcu.extrapolation = 'CONSTANT' + return + + +################################################################################### +# +# initialize and register +# +################################################################################### + def menu_func(self, context): self.layout.operator(ImportMhx.bl_idname, text="MakeHuman (.mhx)...") |