From 9d4e9bdc67128bd76b608e9b279e9e6f443a58f5 Mon Sep 17 00:00:00 2001 From: Luca Bonavita <mindrones@gmail.com> Date: Wed, 22 Dec 2010 23:24:36 +0000 Subject: [PATCH] == make human == Committing the most recent version of make human on behalf of Thomas Larsson (after the tracker upgrade svn plugin has to be fixed, will be done in january). Also formatted bl_addon_info and changed tabs -> spaces. Note: this script belongs to extern/, at due time we'll move it there. --- io_import_scene_mhx.py | 3994 ++++++++++++++++++++-------------------- 1 file changed, 2005 insertions(+), 1989 deletions(-) diff --git a/io_import_scene_mhx.py b/io_import_scene_mhx.py index 982df04a9..5b3aeab44 100644 --- a/io_import_scene_mhx.py +++ b/io_import_scene_mhx.py @@ -1,36 +1,38 @@ """ -**Project Name:** MakeHuman +**Project Name:** MakeHuman **Product Home Page:** http://www.makehuman.org/ -**Code Home Page:** http://code.google.com/p/makehuman/ +**Code Home Page:** http://code.google.com/p/makehuman/ -**Authors:** Thomas Larsson +**Authors:** Thomas Larsson -**Copyright(c):** MakeHuman Team 2001-2010 +**Copyright(c):** MakeHuman Team 2001-2010 -**Licensing:** GPL3 (see also http://sites.google.com/site/makehumandocs/licensing) +**Licensing:** GPL3 (see also http://sites.google.com/site/makehumandocs/licensing) **Coding Standards:** See http://sites.google.com/site/makehumandocs/developers-guide Abstract MHX (MakeHuman eXchange format) importer for Blender 2.5x. -Version 1.0 +Version 1.0.3 """ bl_addon_info = { - 'name': 'Import: MakeHuman (.mhx)', - 'author': 'Thomas Larsson', - 'version': '1.0', - 'blender': (2, 5, 4), - "api": 31913, - "location": "File > Import", - "description": "Import files in the MakeHuman eXchange format (.mhx)", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/File_I-O/Make_Human", - "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=21872&group_id=153&atid=469", - "category": "Import/Export"} + 'name': 'Import: MakeHuman (.mhx)', + 'author': 'Thomas Larsson', + 'version': (1, 0, 3), + 'blender': (2, 5, 5), + 'api': 33590, + 'location': "File > Import", + 'description': 'Import files in the MakeHuman eXchange format (.mhx)', + 'warning': '', + 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\ + 'Scripts/File_I-O/Make_Human', + 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\ + 'func=detail&aid=21872&group_id=153&atid=469', + 'category': 'Import/Export'} """ Place this file in the .blender/scripts/addons dir @@ -40,7 +42,8 @@ Access from the File > Import menu. MAJOR_VERSION = 1 MINOR_VERSION = 0 -BLENDER_VERSION = (2, 54, 0) +SUB_VERSION = 3 +BLENDER_VERSION = (2, 55, 1) # # @@ -51,7 +54,8 @@ import os import time import mathutils from mathutils import * -import string +#import geometry +#import string MHX249 = False Blender24 = False @@ -78,7 +82,7 @@ theTempDatum = None todo = [] # -# toggle flags +# toggle flags # T_EnforceVersion = 0x01 @@ -104,14 +108,14 @@ T_MHX = 0x8000 toggle = T_EnforceVersion + T_Replace + T_Mesh + T_Armature + T_Face + T_Shape + T_Proxy + T_Clothes # -# setFlagsAndFloats(rigFlags): +# setFlagsAndFloats(rigFlags): # -# Global floats +# Global floats #fFingerPanel = 0.0 #fFingerIK = 0.0 fNoStretch = 0.0 -# rigLeg and rigArm flags +# rigLeg and rigArm flags T_Toes = 0x0001 #T_GoboFoot = 0x0002 @@ -130,251 +134,251 @@ T_Toes = 0x0001 #rigArm = 0 def setFlagsAndFloats(): - ''' - global toggle, rigLeg, rigArm + ''' + global toggle, rigLeg, rigArm - (footRig, fingerRig) = rigFlags - rigLeg = 0 - if footRig == 'Reverse foot': - rigLeg |= T_InvFoot - if toggle & T_PoleTar: - rigLeg |= T_InvFootPT - else: - rigLeg |= T_InvFootNoPT - elif footRig == 'Gobo': rigLeg |= T_GoboFoot + (footRig, fingerRig) = rigFlags + rigLeg = 0 + if footRig == 'Reverse foot': + rigLeg |= T_InvFoot + if toggle & T_PoleTar: + rigLeg |= T_InvFootPT + else: + rigLeg |= T_InvFootNoPT + elif footRig == 'Gobo': rigLeg |= T_GoboFoot - rigArm = 0 - if fingerRig == 'Panel': rigArm |= T_FingerPanel - elif fingerRig == 'Rotation': rigArm |= T_FingerRot - elif fingerRig == 'IK': rigArm |= T_FingerIK + rigArm = 0 + if fingerRig == 'Panel': rigArm |= T_FingerPanel + elif fingerRig == 'Rotation': rigArm |= T_FingerRot + elif fingerRig == 'IK': rigArm |= T_FingerIK - toggle |= T_Panel - ''' - global fNoStretch - if toggle&T_Stretch: fNoStretch == 0.0 - else: fNoStretch = 1.0 + toggle |= T_Panel + ''' + global fNoStretch + if toggle&T_Stretch: fNoStretch == 0.0 + else: fNoStretch = 1.0 - return + return # -# Dictionaries +# Dictionaries # loadedData = { - 'NONE' : {}, - - 'Object' : {}, - 'Mesh' : {}, - 'Armature' : {}, - 'Lamp' : {}, - 'Camera' : {}, - 'Lattice' : {}, - 'Curve' : {}, - 'Text' : {}, - - 'Material' : {}, - 'Image' : {}, - 'MaterialTextureSlot' : {}, - 'Texture' : {}, - - 'Bone' : {}, - 'BoneGroup' : {}, - 'Rigify' : {}, - - 'Action' : {}, - 'Group' : {}, - - 'MeshTextureFaceLayer' : {}, - 'MeshColorLayer' : {}, - 'VertexGroup' : {}, - 'ShapeKey' : {}, - 'ParticleSystem' : {}, - - 'ObjectConstraints' : {}, - 'ObjectModifiers' : {}, - 'MaterialSlot' : {}, + 'NONE' : {}, + + 'Object' : {}, + 'Mesh' : {}, + 'Armature' : {}, + 'Lamp' : {}, + 'Camera' : {}, + 'Lattice' : {}, + 'Curve' : {}, + 'Text' : {}, + + 'Material' : {}, + 'Image' : {}, + 'MaterialTextureSlot' : {}, + 'Texture' : {}, + + 'Bone' : {}, + 'BoneGroup' : {}, + 'Rigify' : {}, + + 'Action' : {}, + 'Group' : {}, + + 'MeshTextureFaceLayer' : {}, + 'MeshColorLayer' : {}, + 'VertexGroup' : {}, + 'ShapeKey' : {}, + 'ParticleSystem' : {}, + + 'ObjectConstraints' : {}, + 'ObjectModifiers' : {}, + 'MaterialSlot' : {}, } Plural = { - 'Object' : 'objects', - 'Mesh' : 'meshes', - 'Lattice' : 'lattices', - 'Curve' : 'curves', - 'Text' : 'texts', - 'Group' : 'groups', - 'Empty' : 'empties', - 'Armature' : 'armatures', - 'Bone' : 'bones', - 'BoneGroup' : 'bone_groups', - 'Pose' : 'poses', - 'PoseBone' : 'pose_bones', - 'Material' : 'materials', - 'Texture' : 'textures', - 'Image' : 'images', - 'Camera' : 'cameras', - 'Lamp' : 'lamps', - 'World' : 'worlds', + 'Object' : 'objects', + 'Mesh' : 'meshes', + 'Lattice' : 'lattices', + 'Curve' : 'curves', + 'Text' : 'texts', + 'Group' : 'groups', + 'Empty' : 'empties', + 'Armature' : 'armatures', + 'Bone' : 'bones', + 'BoneGroup' : 'bone_groups', + 'Pose' : 'poses', + 'PoseBone' : 'pose_bones', + 'Material' : 'materials', + 'Texture' : 'textures', + 'Image' : 'images', + 'Camera' : 'cameras', + 'Lamp' : 'lamps', + 'World' : 'worlds', } # -# checkBlenderVersion() +# checkBlenderVersion() # def checkBlenderVersion(): - print("Found Blender", bpy.app.version) - (A, B, C) = bpy.app.version - (a, b, c) = BLENDER_VERSION - if a <= A: return - if b <= B: return - if c <= C: return - msg = ( + print("Found Blender", bpy.app.version) + (A, B, C) = bpy.app.version + (a, b, c) = BLENDER_VERSION + if a <= A: return + if b <= B: return + if c <= C: return + msg = ( "This version of the MHX importer only works with Blender (%d, %d, %d) or later. " % (a, b, c) + "Download a more recent Blender from www.blender.org or www.graphicall.org.\n" - ) - raise NameError(msg) - return + ) + raise NameError(msg) + return # -# readMhxFile(filePath, scale): +# readMhxFile(filePath, scale): # def readMhxFile(filePath, scale): - global todo, nErrors, theScale, defaultScale, One, toggle - - checkBlenderVersion() - - theScale = scale - defaultScale = scale - One = 1.0/theScale - - fileName = os.path.expanduser(filePath) - (shortName, ext) = os.path.splitext(fileName) - if ext.lower() != ".mhx": - print("Error: Not a mhx file: " + fileName) - return - print( "Opening MHX file "+ fileName ) - time1 = time.clock() - - ignore = False - stack = [] - tokens = [] - key = "toplevel" - level = 0 - nErrors = 0 - comment = 0 - nesting = 0 - - setFlagsAndFloats() - - file= open(fileName, "rU") - print( "Tokenizing" ) - lineNo = 0 - for line in file: - # print(line) - lineSplit= line.split() - lineNo += 1 - if len(lineSplit) == 0: - pass - elif lineSplit[0][0] == '#': - if lineSplit[0] == '#if': - if comment == nesting: - try: - res = eval(lineSplit[1]) - except: - res = False - if res: - comment += 1 - nesting += 1 - elif lineSplit[0] == '#else': - if comment == nesting-1: - comment += 1 - elif comment == nesting: - comment -= 1 - elif lineSplit[0] == '#endif': - if comment == nesting: - comment -= 1 - nesting -= 1 - elif comment < nesting: - pass - elif lineSplit[0] == 'end': - try: - sub = tokens - tokens = stack.pop() - if tokens: - tokens[-1][2] = sub - level -= 1 - except: - print( "Tokenizer error at or before line %d" % lineNo ) - print( line ) - dummy = stack.pop() - elif lineSplit[-1] == ';': - if lineSplit[0] == '\\': - key = lineSplit[1] - tokens.append([key,lineSplit[2:-1],[]]) - else: - key = lineSplit[0] - tokens.append([key,lineSplit[1:-1],[]]) - else: - key = lineSplit[0] - tokens.append([key,lineSplit[1:],[]]) - stack.append(tokens) - level += 1 - tokens = [] - file.close() - - if level != 0: - raise NameError("Tokenizer out of kilter %d" % level) - clearScene() - print( "Parsing" ) - parse(tokens) - - for (expr, glbals, lcals) in todo: - try: - print("Doing %s" % expr) - exec(expr, glbals, lcals) - except: - msg = "Failed: "+expr - print( msg ) - nErrors += 1 - #raise NameError(msg) - - print("Postprocess") - postProcess() - print("HideLayers") - hideLayers() - time2 = time.clock() - print("toggle = %x" % toggle) - msg = "File %s loaded in %g s" % (fileName, time2-time1) - if nErrors: - msg += " but there where %d errors. " % (nErrors) - print(msg) - return - -# -# getObject(name, var, glbals, lcals): + global todo, nErrors, theScale, defaultScale, One, toggle + + checkBlenderVersion() + + theScale = scale + defaultScale = scale + One = 1.0/theScale + + fileName = os.path.expanduser(filePath) + (shortName, ext) = os.path.splitext(fileName) + if ext.lower() != ".mhx": + print("Error: Not a mhx file: " + fileName) + return + print( "Opening MHX file "+ fileName ) + time1 = time.clock() + + ignore = False + stack = [] + tokens = [] + key = "toplevel" + level = 0 + nErrors = 0 + comment = 0 + nesting = 0 + + setFlagsAndFloats() + + file= open(fileName, "rU") + print( "Tokenizing" ) + lineNo = 0 + for line in file: + # print(line) + lineSplit= line.split() + lineNo += 1 + if len(lineSplit) == 0: + pass + elif lineSplit[0][0] == '#': + if lineSplit[0] == '#if': + if comment == nesting: + try: + res = eval(lineSplit[1]) + except: + res = False + if res: + comment += 1 + nesting += 1 + elif lineSplit[0] == '#else': + if comment == nesting-1: + comment += 1 + elif comment == nesting: + comment -= 1 + elif lineSplit[0] == '#endif': + if comment == nesting: + comment -= 1 + nesting -= 1 + elif comment < nesting: + pass + elif lineSplit[0] == 'end': + try: + sub = tokens + tokens = stack.pop() + if tokens: + tokens[-1][2] = sub + level -= 1 + except: + print( "Tokenizer error at or before line %d" % lineNo ) + print( line ) + dummy = stack.pop() + elif lineSplit[-1] == ';': + if lineSplit[0] == '\\': + key = lineSplit[1] + tokens.append([key,lineSplit[2:-1],[]]) + else: + key = lineSplit[0] + tokens.append([key,lineSplit[1:-1],[]]) + else: + key = lineSplit[0] + tokens.append([key,lineSplit[1:],[]]) + stack.append(tokens) + level += 1 + tokens = [] + file.close() + + if level != 0: + raise NameError("Tokenizer out of kilter %d" % level) + clearScene() + print( "Parsing" ) + parse(tokens) + + for (expr, glbals, lcals) in todo: + try: + print("Doing %s" % expr) + exec(expr, glbals, lcals) + except: + msg = "Failed: "+expr + print( msg ) + nErrors += 1 + #raise NameError(msg) + + print("Postprocess") + postProcess() + print("HideLayers") + hideLayers() + time2 = time.clock() + print("toggle = %x" % toggle) + msg = "File %s loaded in %g s" % (fileName, time2-time1) + if nErrors: + msg += " but there where %d errors. " % (nErrors) + print(msg) + return + +# +# getObject(name, var, glbals, lcals): # def getObject(name, var, glbals, lcals): - try: - ob = loadedData['Object'][name] - except: - if name != "None": - pushOnTodoList(None, "ob = loadedData['Object'][name]" % globals(), locals()) - ob = None - return ob + try: + ob = loadedData['Object'][name] + except: + if name != "None": + pushOnTodoList(None, "ob = loadedData['Object'][name]" % globals(), locals()) + ob = None + return ob # -# checkMhxVersion(major, minor): +# checkMhxVersion(major, minor): # def checkMhxVersion(major, minor): - global warnedVersion - if major != MAJOR_VERSION or minor != MINOR_VERSION: - if warnedVersion: - return - else: - msg = ( + global warnedVersion + if major != MAJOR_VERSION or minor != MINOR_VERSION: + if warnedVersion: + return + else: + msg = ( "Wrong MHX version\n" + "Expected MHX %d.%d but the loaded file has version MHX %d.%d\n" % (MAJOR_VERSION, MINOR_VERSION, major, minor) + "You can disable this error message by deselecting the Enforce version option when importing. " + @@ -382,2074 +386,2086 @@ def checkMhxVersion(major, minor): "The current version of the import script is located in the importers/mhx/blender25x folder and is called import_scene_mhx.py. " + "The version distributed with Blender builds from www.graphicall.org may be out of date.\n" ) - if toggle & T_EnforceVersion: - raise NameError(msg) - else: - print(msg) - warnedVersion = True - return + if toggle & T_EnforceVersion: + raise NameError(msg) + else: + print(msg) + warnedVersion = True + return # -# parse(tokens): +# parse(tokens): # ifResult = False def parse(tokens): - global MHX249, ifResult, theScale, defaultScale, One - - for (key, val, sub) in tokens: - # print("Parse %s" % key) - data = None - if key == 'MHX': - checkMhxVersion(int(val[0]), int(val[1])) - elif key == 'MHX249': - MHX249 = eval(val[0]) - print("Blender 2.49 compatibility mode is %s\n" % MHX249) - elif MHX249: - pass - elif key == 'print': - msg = concatList(val) - print(msg) - elif key == 'warn': - msg = concatList(val) - print(msg) - elif key == 'error': - msg = concatList(val) - raise NameError(msg) - elif key == 'NoScale': - if eval(val[0]): - theScale = 1.0 - else: - theScale = defaultScale - One = 1.0/theScale - elif key == "Object": - parseObject(val, sub) - elif key == "Mesh": - data = parseMesh(val, sub) - elif key == "Armature": - data = parseArmature(val, sub) - elif key == "Pose": - data = parsePose(val, sub) - elif key == "Action": - data = parseAction(val, sub) - elif key == "Material": - data = parseMaterial(val, sub) - elif key == "Texture": - data = parseTexture(val, sub) - elif key == "Image": - data = parseImage(val, sub) - elif key == "Curve": - data = parseCurve(val, sub) - elif key == "TextCurve": - data = parseTextCurve(val, sub) - elif key == "Lattice": - data = parseLattice(val, sub) - elif key == "Group": - data = parseGroup(val, sub) - elif key == "Lamp": - data = parseLamp(val, sub) - elif key == "World": - data = parseWorld(val, sub) - elif key == "Scene": - data = parseScene(val, sub) - elif key == "Process": - parseProcess(val, sub) - elif key == 'AnimationData': - try: - ob = loadedData['Object'][val[0]] - except: - ob = None - if ob: - bpy.context.scene.objects.active = ob - parseAnimationData(ob, val, sub) - elif key == 'ShapeKeys': - try: - ob = loadedData['Object'][val[0]] - except: - ob = None - if ob: - bpy.context.scene.objects.active = ob - parseShapeKeys(ob, ob.data, val, sub) - else: - data = parseDefaultType(key, val, sub) - - if data and key != 'Mesh': - print( data ) - return - -# -# parseDefaultType(typ, args, tokens): + global MHX249, ifResult, theScale, defaultScale, One + + for (key, val, sub) in tokens: + # print("Parse %s" % key) + data = None + if key == 'MHX': + checkMhxVersion(int(val[0]), int(val[1])) + elif key == 'MHX249': + MHX249 = eval(val[0]) + print("Blender 2.49 compatibility mode is %s\n" % MHX249) + elif MHX249: + pass + elif key == 'print': + msg = concatList(val) + print(msg) + elif key == 'warn': + msg = concatList(val) + print(msg) + elif key == 'error': + msg = concatList(val) + raise NameError(msg) + elif key == 'NoScale': + if eval(val[0]): + theScale = 1.0 + else: + theScale = defaultScale + One = 1.0/theScale + elif key == "Object": + parseObject(val, sub) + elif key == "Mesh": + data = parseMesh(val, sub) + elif key == "Armature": + data = parseArmature(val, sub) + elif key == "Pose": + data = parsePose(val, sub) + elif key == "Action": + data = parseAction(val, sub) + elif key == "Material": + data = parseMaterial(val, sub) + elif key == "Texture": + data = parseTexture(val, sub) + elif key == "Image": + data = parseImage(val, sub) + elif key == "Curve": + data = parseCurve(val, sub) + elif key == "TextCurve": + data = parseTextCurve(val, sub) + elif key == "Lattice": + data = parseLattice(val, sub) + elif key == "Group": + data = parseGroup(val, sub) + elif key == "Lamp": + data = parseLamp(val, sub) + elif key == "World": + data = parseWorld(val, sub) + elif key == "Scene": + data = parseScene(val, sub) + elif key == "Process": + parseProcess(val, sub) + elif key == 'AnimationData': + try: + ob = loadedData['Object'][val[0]] + except: + ob = None + if ob: + bpy.context.scene.objects.active = ob + parseAnimationData(ob, val, sub) + elif key == 'MaterialAnimationData': + try: + ob = loadedData['Object'][val[0]] + except: + ob = None + if ob: + bpy.context.scene.objects.active = ob + mat = ob.data.materials[int(val[2])] + print("matanim", ob, mat) + parseAnimationData(mat, val, sub) + elif key == 'ShapeKeys': + try: + ob = loadedData['Object'][val[0]] + except: + raise NameError("ShapeKeys object %s does not exist" % val[0]) + if ob: + bpy.context.scene.objects.active = ob + parseShapeKeys(ob, ob.data, val, sub) + else: + data = parseDefaultType(key, val, sub) + + if data and key != 'Mesh': + print( data ) + return + +# +# parseDefaultType(typ, args, tokens): # def parseDefaultType(typ, args, tokens): - global todo + global todo - name = args[0] - data = None - expr = "bpy.data.%s.new('%s')" % (Plural[typ], name) - print(expr) - data = eval(expr) - print(" ok", data) + name = args[0] + data = None + expr = "bpy.data.%s.new('%s')" % (Plural[typ], name) + print(expr) + data = eval(expr) + print(" ok", data) - bpyType = typ.capitalize() - print(bpyType, name, data) - loadedData[bpyType][name] = data - if data == None: - return None + bpyType = typ.capitalize() + print(bpyType, name, data) + loadedData[bpyType][name] = data + if data == None: + return None - for (key, val, sub) in tokens: - #print("%s %s" % (key, val)) - defaultKey(key, val, sub, 'data', [], globals(), locals()) - print("Done ", data) - return data - + for (key, val, sub) in tokens: + #print("%s %s" % (key, val)) + defaultKey(key, val, sub, 'data', [], globals(), locals()) + print("Done ", data) + return data + # -# concatList(elts) +# concatList(elts) # def concatList(elts): - string = "" - for elt in elts: - string += " %s" % elt - return string + string = "" + for elt in elts: + string += " %s" % elt + return string # -# parseAction(args, tokens): -# parseFCurve(fcu, args, tokens): -# parseKeyFramePoint(pt, args, tokens): +# parseAction(args, tokens): +# parseFCurve(fcu, args, tokens): +# parseKeyFramePoint(pt, args, tokens): # def parseAction(args, tokens): - name = args[0] - if invalid(args[1]): - return - - ob = bpy.context.object - bpy.ops.object.mode_set(mode='POSE') - if ob.animation_data: - ob.animation_data.action = None - created = {} - for (key, val, sub) in tokens: - if key == 'FCurve': - prepareActionFCurve(ob, created, val, sub) - - act = ob.animation_data.action - loadedData['Action'][name] = act - if act == None: - print("Ignoring action %s" % name) - return act - act.name = name - print("Action", name, act, ob) - - for (key, val, sub) in tokens: - if key == 'FCurve': - fcu = parseActionFCurve(act, ob, val, sub) - else: - defaultKey(key, val, sub, 'act', [], globals(), locals()) - ob.animation_data.action = None - bpy.ops.object.mode_set(mode='OBJECT') - return act - -def prepareActionFCurve(ob, created, args, tokens): - dataPath = args[0] - index = args[1] - (expr, channel) = channelFromDataPath(dataPath, index) - try: - if channel in created[expr]: - return - else: - created[expr].append(channel) - except: - created[expr] = [channel] - - times = [] - for (key, val, sub) in tokens: - if key == 'kp': - times.append(int(val[0])) - - try: - data = eval(expr) - except: - print("Ignoring illegal expression: %s" % expr) - return - - n = 0 - for t in times: - #bpy.context.scene.current_frame = t - bpy.ops.anim.change_frame(frame = t) - try: - data.keyframe_insert(channel) - n += 1 - except: - pass - #print("failed", data, expr, channel) - if n != len(times): - print("Mismatch", n, len(times), expr, channel) - return + name = args[0] + if invalid(args[1]): + return + + ob = bpy.context.object + bpy.ops.object.mode_set(mode='POSE') + if ob.animation_data: + ob.animation_data.action = None + created = {} + for (key, val, sub) in tokens: + if key == 'FCurve': + prepareActionFCurve(ob, created, val, sub) + + act = ob.animation_data.action + loadedData['Action'][name] = act + if act == None: + print("Ignoring action %s" % name) + return act + act.name = name + print("Action", name, act, ob) + + for (key, val, sub) in tokens: + if key == 'FCurve': + fcu = parseActionFCurve(act, ob, val, sub) + else: + defaultKey(key, val, sub, 'act', [], globals(), locals()) + ob.animation_data.action = None + bpy.ops.object.mode_set(mode='OBJECT') + return act + +def prepareActionFCurve(ob, created, args, tokens): + dataPath = args[0] + index = args[1] + (expr, channel) = channelFromDataPath(dataPath, index) + try: + if channel in created[expr]: + return + else: + created[expr].append(channel) + except: + created[expr] = [channel] + + times = [] + for (key, val, sub) in tokens: + if key == 'kp': + times.append(int(val[0])) + + try: + data = eval(expr) + except: + print("Ignoring illegal expression: %s" % expr) + return + + n = 0 + for t in times: + #bpy.context.scene.current_frame = t + bpy.ops.anim.change_frame(frame = t) + try: + data.keyframe_insert(channel) + n += 1 + except: + pass + #print("failed", data, expr, channel) + if n != len(times): + print("Mismatch", n, len(times), expr, channel) + return def channelFromDataPath(dataPath, index): - words = dataPath.split(']') - if len(words) == 1: - # location - expr = "ob" - channel = dataPath - elif len(words) == 2: - # pose.bones["tongue"].location - expr = "ob.%s]" % (words[0]) - cwords = words[1].split('.') - channel = cwords[1] - elif len(words) == 3: - # pose.bones["brow.R"]["mad"] - expr = "ob.%s]" % (words[0]) - cwords = words[1].split('"') - channel = cwords[1] - # print(expr, channel, index) - return (expr, channel) + words = dataPath.split(']') + if len(words) == 1: + # location + expr = "ob" + channel = dataPath + elif len(words) == 2: + # pose.bones["tongue"].location + expr = "ob.%s]" % (words[0]) + cwords = words[1].split('.') + channel = cwords[1] + elif len(words) == 3: + # pose.bones["brow.R"]["mad"] + expr = "ob.%s]" % (words[0]) + cwords = words[1].split('"') + channel = cwords[1] + # print(expr, channel, index) + return (expr, channel) def parseActionFCurve(act, ob, args, tokens): - dataPath = args[0] - index = args[1] - (expr, channel) = channelFromDataPath(dataPath, index) - index = int(args[1]) - - success = False - for fcu in act.fcurves: - (expr1, channel1) = channelFromDataPath(fcu.data_path, fcu.array_index) - if expr1 == expr and channel1 == channel and fcu.array_index == index: - success = True - break - if not success: - return None - - n = 0 - for (key, val, sub) in tokens: - if key == 'kp': - try: - pt = fcu.keyframe_points[n] - pt.interpolation = 'LINEAR' - pt = parseKeyFramePoint(pt, val, sub) - n += 1 - except: - pass - #print(tokens) - #raise NameError("kp", fcu, n, len(fcu.keyframe_points), val) - else: - defaultKey(key, val, sub, 'fcu', [], globals(), locals()) - return fcu + dataPath = args[0] + index = args[1] + (expr, channel) = channelFromDataPath(dataPath, index) + index = int(args[1]) + + success = False + for fcu in act.fcurves: + (expr1, channel1) = channelFromDataPath(fcu.data_path, fcu.array_index) + if expr1 == expr and channel1 == channel and fcu.array_index == index: + success = True + break + if not success: + return None + + n = 0 + for (key, val, sub) in tokens: + if key == 'kp': + try: + pt = fcu.keyframe_points[n] + pt.interpolation = 'LINEAR' + pt = parseKeyFramePoint(pt, val, sub) + n += 1 + except: + pass + #print(tokens) + #raise NameError("kp", fcu, n, len(fcu.keyframe_points), val) + else: + defaultKey(key, val, sub, 'fcu', [], globals(), locals()) + return fcu def parseKeyFramePoint(pt, args, tokens): - pt.co = (float(args[0]), float(args[1])) - if len(args) > 2: - pt.handle1 = (float(args[2]), float(args[3])) - pt.handle2 = (float(args[3]), float(args[5])) - return pt + pt.co = (float(args[0]), float(args[1])) + if len(args) > 2: + pt.handle1 = (float(args[2]), float(args[3])) + pt.handle2 = (float(args[3]), float(args[5])) + return pt # -# parseAnimationData(rna, args, tokens): -# parseDriver(drv, args, tokens): -# parseDriverVariable(var, args, tokens): +# parseAnimationData(rna, args, tokens): +# parseDriver(drv, args, tokens): +# parseDriverVariable(var, args, tokens): # def parseAnimationData(rna, args, tokens): - if not eval(args[1]): - return - if rna.animation_data == None: - rna.animation_data_create() - adata = rna.animation_data - for (key, val, sub) in tokens: - if key == 'FCurve': - fcu = parseAnimDataFCurve(adata, rna, val, sub) - else: - defaultKey(key, val, sub, 'adata', [], globals(), locals()) - return adata + if not eval(args[1]): + return + if rna.animation_data == None: + rna.animation_data_create() + adata = rna.animation_data + for (key, val, sub) in tokens: + if key == 'FCurve': + fcu = parseAnimDataFCurve(adata, rna, val, sub) + else: + defaultKey(key, val, sub, 'adata', [], globals(), locals()) + return adata def parseAnimDataFCurve(adata, rna, args, tokens): - if invalid(args[2]): - return - dataPath = args[0] - index = int(args[1]) - # print("parseAnimDataFCurve", adata, dataPath, index) - for (key, val, sub) in tokens: - if key == 'Driver': - fcu = parseDriver(adata, dataPath, index, rna, val, sub) - elif key == 'FModifier': - parseFModifier(fcu, val, sub) - else: - defaultKey(key, val, sub, 'fcu', [], globals(), locals()) - return fcu + if invalid(args[2]): + return + dataPath = args[0] + index = int(args[1]) + # print("parseAnimDataFCurve", adata, dataPath, index) + n = 1 + for (key, val, sub) in tokens: + if key == 'Driver': + fcu = parseDriver(adata, dataPath, index, rna, val, sub) + fmod = fcu.modifiers[0] + fcu.modifiers.remove(fmod) + elif key == 'FModifier': + parseFModifier(fcu, val, sub) + elif key == 'kp': + pt = fcu.keyframe_points.add(n, 0) + pt.interpolation = 'LINEAR' + pt = parseKeyFramePoint(pt, val, sub) + n += 1 + else: + defaultKey(key, val, sub, 'fcu', [], globals(), locals()) + return fcu """ - fcurve = con.driver_add("influence", 0) - driver = fcurve.driver - driver.type = 'AVERAGE' + fcurve = con.driver_add("influence", 0) + driver = fcurve.driver + driver.type = 'AVERAGE' """ def parseDriver(adata, dataPath, index, rna, args, tokens): - if dataPath[-1] == ']': - words = dataPath.split(']') - expr = "rna." + words[0] + ']' - pwords = words[1].split('"') - prop = pwords[1] - # print("prop", expr, prop) - bone = eval(expr) - return None - else: - words = dataPath.split('.') - channel = words[-1] - expr = "rna" - for n in range(len(words)-1): - expr += "." + words[n] - expr += ".driver_add('%s', index)" % channel - - # print("expr", rna, expr) - fcu = eval(expr) - drv = fcu.driver - drv.type = args[0] - for (key, val, sub) in tokens: - if key == 'DriverVariable': - var = parseDriverVariable(drv, rna, val, sub) - else: - defaultKey(key, val, sub, 'drv', [], globals(), locals()) - return fcu + if dataPath[-1] == ']': + words = dataPath.split(']') + expr = "rna." + words[0] + ']' + pwords = words[1].split('"') + prop = pwords[1] + # print("prop", expr, prop) + bone = eval(expr) + return None + else: + words = dataPath.split('.') + channel = words[-1] + expr = "rna" + for n in range(len(words)-1): + expr += "." + words[n] + expr += ".driver_add('%s', index)" % channel + + #print("expr", rna, expr) + fcu = eval(expr) + drv = fcu.driver + drv.type = args[0] + for (key, val, sub) in tokens: + if key == 'DriverVariable': + var = parseDriverVariable(drv, rna, val, sub) + else: + defaultKey(key, val, sub, 'drv', [], globals(), locals()) + return fcu def parseDriverVariable(drv, rna, args, tokens): - var = drv.variables.new() - var.name = args[0] - var.type = args[1] - nTarget = 0 - # print("var", var, var.name, var.type) - for (key, val, sub) in tokens: - if key == 'Target': - parseDriverTarget(var, nTarget, rna, val, sub) - nTarget += 1 - else: - defaultKey(key, val, sub, 'var', [], globals(), locals()) - return var + var = drv.variables.new() + var.name = args[0] + var.type = args[1] + nTarget = 0 + # print("var", var, var.name, var.type) + for (key, val, sub) in tokens: + if key == 'Target': + parseDriverTarget(var, nTarget, rna, val, sub) + nTarget += 1 + else: + defaultKey(key, val, sub, 'var', [], globals(), locals()) + return var def parseFModifier(fcu, args, tokens): - #fmod = fcu.modifiers.new() - fmod = fcu.modifiers[0] - #fmod.type = args[0] - #print("fmod", fmod, fmod.type) - for (key, val, sub) in tokens: - defaultKey(key, val, sub, 'fmod', [], globals(), locals()) - return fmod + fmod = fcu.modifiers.new(args[0]) + #fmod = fcu.modifiers[0] + for (key, val, sub) in tokens: + defaultKey(key, val, sub, 'fmod', [], globals(), locals()) + return fmod """ - var = driver.variables.new() - var.name = target_bone - var.targets[0].id_type = 'OBJECT' - var.targets[0].id = obj - var.targets[0].rna_path = driver_path + var = driver.variables.new() + var.name = target_bone + var.targets[0].id_type = 'OBJECT' + var.targets[0].id = obj + var.targets[0].rna_path = driver_path """ def parseDriverTarget(var, nTarget, rna, args, tokens): - targ = var.targets[nTarget] - targ.id = loadedData['Object'][args[0]] - for (key, val, sub) in tokens: - defaultKey(key, val, sub, 'targ', [], globals(), locals()) - return targ + targ = var.targets[nTarget] + targ.id = loadedData['Object'][args[0]] + for (key, val, sub) in tokens: + defaultKey(key, val, sub, 'targ', [], globals(), locals()) + return targ - + # -# parseMaterial(args, ext, tokens): -# parseMTex(mat, args, tokens): -# parseTexture(args, tokens): +# parseMaterial(args, ext, tokens): +# parseMTex(mat, args, tokens): +# parseTexture(args, tokens): # def parseMaterial(args, tokens): - global todo - name = args[0] - mat = bpy.data.materials.new(name) - if mat == None: - return None - loadedData['Material'][name] = mat - for (key, val, sub) in tokens: - if key == 'MTex': - parseMTex(mat, val, sub) - elif key == 'Ramp': - parseRamp(mat, val, sub) - elif key == 'RaytraceTransparency': - parseDefault(mat.raytrace_transparency, sub, {}, []) - elif key == 'Halo': - parseDefault(mat.halo, sub, {}, []) - elif key == 'SSS': - parseDefault(mat.subsurface_scattering, sub, {}, []) - elif key == 'Strand': - parseDefault(mat.strand, sub, {}, []) - elif key == 'NodeTree': - mat.use_nodes = True - parseNodeTree(mat.node_tree, val, sub) - else: - exclude = ['specular_intensity', 'tangent_shading'] - defaultKey(key, val, sub, 'mat', [], globals(), locals()) - - return mat + global todo + name = args[0] + mat = bpy.data.materials.new(name) + if mat == None: + return None + loadedData['Material'][name] = mat + for (key, val, sub) in tokens: + if key == 'MTex': + parseMTex(mat, val, sub) + elif key == 'Ramp': + parseRamp(mat, val, sub) + elif key == 'RaytraceTransparency': + parseDefault(mat.raytrace_transparency, sub, {}, []) + elif key == 'Halo': + parseDefault(mat.halo, sub, {}, []) + elif key == 'SSS': + parseDefault(mat.subsurface_scattering, sub, {}, []) + elif key == 'Strand': + parseDefault(mat.strand, sub, {}, []) + elif key == 'NodeTree': + mat.use_nodes = True + parseNodeTree(mat.node_tree, val, sub) + else: + exclude = ['specular_intensity', 'tangent_shading'] + defaultKey(key, val, sub, 'mat', [], globals(), locals()) + + return mat def parseMTex(mat, args, tokens): - global todo - index = int(args[0]) - texname = args[1] - texco = args[2] - mapto = args[3] - tex = loadedData['Texture'][texname] - mtex = mat.texture_slots.add() - mtex.texture_coords = texco - mtex.texture = tex + global todo + index = int(args[0]) + texname = args[1] + texco = args[2] + mapto = args[3] + tex = loadedData['Texture'][texname] + mtex = mat.texture_slots.add() + mtex.texture_coords = texco + mtex.texture = tex - for (key, val, sub) in tokens: - defaultKey(key, val, sub, "mtex", [], globals(), locals()) + for (key, val, sub) in tokens: + defaultKey(key, val, sub, "mtex", [], globals(), locals()) - return mtex + return mtex def parseTexture(args, tokens): - global todo - if verbosity > 2: - print( "Parsing texture %s" % args ) - name = args[0] - tex = bpy.data.textures.new(name=name, type=args[1]) - loadedData['Texture'][name] = tex - - for (key, val, sub) in tokens: - if key == 'Image': - try: - imgName = val[0] - img = loadedData['Image'][imgName] - tex.image = img - except: - msg = "Unable to load image '%s'" % val[0] - elif key == 'Ramp': - parseRamp(tex, val, sub) - elif key == 'NodeTree': - tex.use_nodes = True - parseNodeTree(tex.node_tree, val, sub) - else: - defaultKey(key, val, sub, "tex", ['use_nodes', 'use_textures', 'contrast'], globals(), locals()) - - return tex + global todo + if verbosity > 2: + print( "Parsing texture %s" % args ) + name = args[0] + tex = bpy.data.textures.new(name=name, type=args[1]) + loadedData['Texture'][name] = tex + + for (key, val, sub) in tokens: + if key == 'Image': + try: + imgName = val[0] + img = loadedData['Image'][imgName] + tex.image = img + except: + msg = "Unable to load image '%s'" % val[0] + elif key == 'Ramp': + parseRamp(tex, val, sub) + elif key == 'NodeTree': + tex.use_nodes = True + parseNodeTree(tex.node_tree, val, sub) + else: + defaultKey(key, val, sub, "tex", ['use_nodes', 'use_textures', 'contrast'], globals(), locals()) + + return tex def parseRamp(data, args, tokens): - nvar = "data.%s" % args[0] - use = "data.use_%s = True" % args[0] - exec(use) - ramp = eval(nvar) - elts = ramp.elements - n = 0 - for (key, val, sub) in tokens: - # print("Ramp", key, val) - if key == 'Element': - elts[n].color = eval(val[0]) - elts[n].position = eval(val[1]) - n += 1 - else: - defaultKey(key, val, sub, "tex", ['use_nodes', 'use_textures', 'contrast'], globals(), locals()) - + nvar = "data.%s" % args[0] + use = "data.use_%s = True" % args[0] + exec(use) + ramp = eval(nvar) + elts = ramp.elements + n = 0 + for (key, val, sub) in tokens: + # print("Ramp", key, val) + if key == 'Element': + elts[n].color = eval(val[0]) + elts[n].position = eval(val[1]) + n += 1 + else: + defaultKey(key, val, sub, "tex", ['use_nodes', 'use_textures', 'contrast'], globals(), locals()) + def parseSSS(mat, args, tokens): - sss = mat.subsurface_scattering - for (key, val, sub) in tokens: - defaultKey(key, val, sub, "sss", [], globals(), locals()) + sss = mat.subsurface_scattering + for (key, val, sub) in tokens: + defaultKey(key, val, sub, "sss", [], globals(), locals()) def parseStrand(mat, args, tokens): - strand = mat.strand - for (key, val, sub) in tokens: - defaultKey(key, val, sub, "strand", [], globals(), locals()) + strand = mat.strand + for (key, val, sub) in tokens: + defaultKey(key, val, sub, "strand", [], globals(), locals()) # -# parseNodeTree(tree, args, tokens): -# parseNode(node, args, tokens): -# parseSocket(socket, args, tokens): +# parseNodeTree(tree, args, tokens): +# parseNode(node, args, tokens): +# parseSocket(socket, args, tokens): # def parseNodeTree(tree, args, tokens): - return - print("Tree", tree, args) - print(list(tree.nodes)) - tree.name = args[0] - for (key, val, sub) in tokens: - if key == 'Node': - parseNodes(tree.nodes, val, sub) - else: - defaultKey(key, val, sub, "tree", [], globals(), locals()) + return + print("Tree", tree, args) + print(list(tree.nodes)) + tree.name = args[0] + for (key, val, sub) in tokens: + if key == 'Node': + parseNodes(tree.nodes, val, sub) + else: + defaultKey(key, val, sub, "tree", [], globals(), locals()) def parseNodes(nodes, args, tokens): - print("Nodes", nodes, args) - print(list(nodes)) - node.name = args[0] - for (key, val, sub) in tokens: - if key == 'Inputs': - parseSocket(node.inputs, val, sub) - elif key == 'Outputs': - parseSocket(node.outputs, val, sub) - else: - defaultKey(key, val, sub, "node", [], globals(), locals()) + print("Nodes", nodes, args) + print(list(nodes)) + node.name = args[0] + for (key, val, sub) in tokens: + if key == 'Inputs': + parseSocket(node.inputs, val, sub) + elif key == 'Outputs': + parseSocket(node.outputs, val, sub) + else: + defaultKey(key, val, sub, "node", [], globals(), locals()) def parseNode(node, args, tokens): - print("Node", node, args) - print(list(node.inputs), list(node.outputs)) - node.name = args[0] - for (key, val, sub) in tokens: - if key == 'Inputs': - parseSocket(node.inputs, val, sub) - elif key == 'Outputs': - parseSocket(node.outputs, val, sub) - else: - defaultKey(key, val, sub, "node", [], globals(), locals()) + print("Node", node, args) + print(list(node.inputs), list(node.outputs)) + node.name = args[0] + for (key, val, sub) in tokens: + if key == 'Inputs': + parseSocket(node.inputs, val, sub) + elif key == 'Outputs': + parseSocket(node.outputs, val, sub) + else: + defaultKey(key, val, sub, "node", [], globals(), locals()) def parseSocket(socket, args, tokens): - print("Socket", socket, args) - socket.name = args[0] - for (key, val, sub) in tokens: - if key == 'Node': - parseNode(tree.nodes, val, sub) - else: - defaultKey(key, val, sub, "tree", [], globals(), locals()) + print("Socket", socket, args) + socket.name = args[0] + for (key, val, sub) in tokens: + if key == 'Node': + parseNode(tree.nodes, val, sub) + else: + defaultKey(key, val, sub, "tree", [], globals(), locals()) # -# doLoadImage(filepath): -# loadImage(filepath): -# parseImage(args, tokens): +# doLoadImage(filepath): +# loadImage(filepath): +# parseImage(args, tokens): # -def doLoadImage(filepath): - path1 = os.path.expanduser(filepath) - file1 = os.path.realpath(path1) - if os.path.isfile(file1): - print( "Found file "+file1 ) - try: - img = bpy.data.images.load(file1) - return img - except: - print( "Cannot read image" ) - return None - else: - print( "No file "+file1 ) - return None +def doLoadImage(filepath): + path1 = os.path.expanduser(filepath) + file1 = os.path.realpath(path1) + if os.path.isfile(file1): + print( "Found file "+file1 ) + try: + img = bpy.data.images.load(file1) + return img + except: + print( "Cannot read image" ) + return None + else: + print( "No file "+file1 ) + return None def loadImage(filepath): - global TexDir, warnedTextureDir, loadedData - - texDir = os.path.expanduser(TexDir) - path1 = os.path.expanduser(filepath) - file1 = os.path.realpath(path1) - (path, filename) = os.path.split(file1) - (name, ext) = os.path.splitext(filename) - print( "Loading ", filepath, " = ", filename ) - - # img = doLoadImage(texDir+"/"+name+".png") - # if img: - # return img - - img = doLoadImage(texDir+"/"+filename) - if img: - return img - - # img = doLoadImage(path+"/"+name+".png") - # if img: - # return img - - img = doLoadImage(path+"/"+filename) - if img: - return img - - if warnedTextureDir: - return None - warnedTextureDir = True - return None - TexDir = Draw.PupStrInput("TexDir? ", path, 100) - - texDir = os.path.expanduser(TexDir) - img = doLoadImage(texDir+"/"+name+".png") - if img: - return img - - img = doLoadImage(TexDir+"/"+filename) - return img - + global TexDir, warnedTextureDir, loadedData + + texDir = os.path.expanduser(TexDir) + path1 = os.path.expanduser(filepath) + file1 = os.path.realpath(path1) + (path, filename) = os.path.split(file1) + (name, ext) = os.path.splitext(filename) + print( "Loading ", filepath, " = ", filename ) + + # img = doLoadImage(texDir+"/"+name+".png") + # if img: + # return img + + img = doLoadImage(texDir+"/"+filename) + if img: + return img + + # img = doLoadImage(path+"/"+name+".png") + # if img: + # return img + + img = doLoadImage(path+"/"+filename) + if img: + return img + + if warnedTextureDir: + return None + warnedTextureDir = True + return None + TexDir = Draw.PupStrInput("TexDir? ", path, 100) + + texDir = os.path.expanduser(TexDir) + img = doLoadImage(texDir+"/"+name+".png") + if img: + return img + + img = doLoadImage(TexDir+"/"+filename) + return img + def parseImage(args, tokens): - global todo - imgName = args[0] - img = None - for (key, val, sub) in tokens: - if key == 'Filename': - filename = val[0] - for n in range(1,len(val)): - filename += " " + val[n] - img = loadImage(filename) - if img == None: - return None - img.name = imgName - else: - defaultKey(key, val, sub, "img", ['depth', 'dirty', 'has_data', 'size', 'type'], globals(), locals()) - print ("Image %s" % img ) - loadedData['Image'][imgName] = img - return img - -# -# parseObject(args, tokens): -# createObject(type, name, data, datName): -# setObjectAndData(args, typ): -# - + global todo + imgName = args[0] + img = None + for (key, val, sub) in tokens: + if key == 'Filename': + filename = val[0] + for n in range(1,len(val)): + filename += " " + val[n] + img = loadImage(filename) + if img == None: + return None + img.name = imgName + else: + defaultKey(key, val, sub, "img", ['depth', 'dirty', 'has_data', 'size', 'type'], globals(), locals()) + print ("Image %s" % img ) + loadedData['Image'][imgName] = img + return img + +# +# parseObject(args, tokens): +# createObject(type, name, data, datName): +# setObjectAndData(args, typ): +# + def parseObject(args, tokens): - if verbosity > 2: - print( "Parsing object %s" % args ) - name = args[0] - typ = args[1] - datName = args[2] - - if typ == 'EMPTY': - print("EMPTY") - ob = bpy.data.objects.new(name, None) - loadedData['Object'][name] = ob - linkObject(ob, None) - else: - try: - data = loadedData[typ.capitalize()][datName] - except: - raise NameError("Failed to find data: %s %s %s" % (name, typ, datName)) - return - - try: - ob = loadedData['Object'][name] - bpy.context.scene.objects.active = ob - #print("Found data", ob) - except: - ob = None - - if ob == None: - print("Create", name, data, datName) - ob = createObject(typ, name, data, datName) - print("created", ob) - linkObject(ob, data) - - for (key, val, sub) in tokens: - if key == 'Modifier': - parseModifier(ob, val, sub) - elif key == 'Constraint': - parseConstraint(ob.constraints, val, sub) - elif key == 'AnimationData': - parseAnimationData(ob, val, sub) - elif key == 'ParticleSystem': - parseParticleSystem(ob, val, sub) - elif key == 'FieldSettings': - parseDefault(ob.field, sub, {}, []) - else: - defaultKey(key, val, sub, "ob", ['type', 'data'], globals(), locals()) - - # Needed for updating layers - if bpy.context.object == ob: - pass - ''' - if ob.data in ['MESH', 'ARMATURE']: - print(ob, ob.data) - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.object.mode_set(mode='OBJECT') - ''' - else: - print("Context", ob, bpy.context.object, bpy.context.scene.objects.active) - return + if verbosity > 2: + print( "Parsing object %s" % args ) + name = args[0] + typ = args[1] + datName = args[2] + + if typ == 'EMPTY': + ob = bpy.data.objects.new(name, None) + loadedData['Object'][name] = ob + linkObject(ob, None) + else: + try: + data = loadedData[typ.capitalize()][datName] + except: + raise NameError("Failed to find data: %s %s %s" % (name, typ, datName)) + return + + try: + ob = loadedData['Object'][name] + bpy.context.scene.objects.active = ob + #print("Found data", ob) + except: + ob = None + + if ob == None: + print("Create", name, data, datName) + ob = createObject(typ, name, data, datName) + print("created", ob) + linkObject(ob, data) + + for (key, val, sub) in tokens: + if key == 'Modifier': + parseModifier(ob, val, sub) + elif key == 'Constraint': + parseConstraint(ob.constraints, val, sub) + elif key == 'AnimationData': + parseAnimationData(ob, val, sub) + elif key == 'ParticleSystem': + parseParticleSystem(ob, val, sub) + elif key == 'FieldSettings': + parseDefault(ob.field, sub, {}, []) + else: + defaultKey(key, val, sub, "ob", ['type', 'data'], globals(), locals()) + + # Needed for updating layers + if bpy.context.object == ob: + pass + ''' + if ob.data in ['MESH', 'ARMATURE']: + print(ob, ob.data) + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.object.mode_set(mode='OBJECT') + ''' + else: + print("Context", ob, bpy.context.object, bpy.context.scene.objects.active) + return def createObject(typ, name, data, datName): - # print( "Creating object %s %s %s" % (typ, name, data) ) - ob = bpy.data.objects.new(name, data) - if data: - loadedData[typ.capitalize()][datName] = data - loadedData['Object'][name] = ob - return ob - + # print( "Creating object %s %s %s" % (typ, name, data) ) + ob = bpy.data.objects.new(name, data) + if data: + loadedData[typ.capitalize()][datName] = data + loadedData['Object'][name] = ob + return ob + def linkObject(ob, data): - #print("Data", data, ob.data) - if data and ob.data == None: - ob.data = data - print("Data linked", ob, ob.data) - scn = bpy.context.scene - scn.objects.link(ob) - scn.objects.active = ob - #print("Linked object", ob) - #print("Scene", scn) - #print("Active", scn.objects.active) - #print("Context", bpy.context.object) - return ob + #print("Data", data, ob.data) + if data and ob.data == None: + ob.data = data + print("Data linked", ob, ob.data) + scn = bpy.context.scene + scn.objects.link(ob) + scn.objects.active = ob + #print("Linked object", ob) + #print("Scene", scn) + #print("Active", scn.objects.active) + #print("Context", bpy.context.object) + return ob def setObjectAndData(args, typ): - datName = args[0] - obName = args[1] - #bpy.ops.object.add(type=typ) - ob = bpy.context.object - ob.name = obName - ob.data.name = datName - loadedData[typ][datName] = ob.data - loadedData['Object'][obName] = ob - return ob.data + datName = args[0] + obName = args[1] + #bpy.ops.object.add(type=typ) + ob = bpy.context.object + ob.name = obName + ob.data.name = datName + loadedData[typ][datName] = ob.data + loadedData['Object'][obName] = ob + return ob.data # -# parseModifier(ob, args, tokens): +# parseModifier(ob, args, tokens): # def parseModifier(ob, args, tokens): - name = args[0] - typ = args[1] - if typ == 'PARTICLE_SYSTEM': - return None - mod = ob.modifiers.new(name, typ) - for (key, val, sub) in tokens: - defaultKey(key, val, sub, 'mod', [], globals(), locals()) - return mod + name = args[0] + typ = args[1] + if typ == 'PARTICLE_SYSTEM': + return None + mod = ob.modifiers.new(name, typ) + for (key, val, sub) in tokens: + defaultKey(key, val, sub, 'mod', [], globals(), locals()) + return mod # -# parseParticleSystem(ob, args, tokens): -# parseParticles(particles, args, tokens): -# parseParticle(par, args, tokens): +# parseParticleSystem(ob, args, tokens): +# parseParticles(particles, args, tokens): +# parseParticle(par, args, tokens): # def parseParticleSystem(ob, args, tokens): - print(ob, bpy.context.object) - pss = ob.particle_systems - print(pss, pss.values()) - name = args[0] - typ = args[1] - #psys = pss.new(name, typ) - bpy.ops.object.particle_system_add() - print(pss, pss.values()) - psys = pss[-1] - psys.name = name - psys.settings.type = typ - loadedData['ParticleSystem'][name] = psys - print("Psys", psys) - - for (key, val, sub) in tokens: - if key == 'Particles': - parseParticles(psys, val, sub) - else: - defaultKey(key, val, sub, 'psys', [], globals(), locals()) - return psys + print(ob, bpy.context.object) + pss = ob.particle_systems + print(pss, pss.values()) + name = args[0] + typ = args[1] + #psys = pss.new(name, typ) + bpy.ops.object.particle_system_add() + print(pss, pss.values()) + psys = pss[-1] + psys.name = name + psys.settings.type = typ + loadedData['ParticleSystem'][name] = psys + print("Psys", psys) + + for (key, val, sub) in tokens: + if key == 'Particles': + parseParticles(psys, val, sub) + else: + defaultKey(key, val, sub, 'psys', [], globals(), locals()) + return psys def parseParticles(psys, args, tokens): - particles = psys.particles - bpy.ops.particle.particle_edit_toggle() - n = 0 - for (key, val, sub) in tokens: - if key == 'Particle': - parseParticle(particles[n], val, sub) - n += 1 - else: - for par in particles: - defaultKey(key, val, sub, 'par', [], globals(), locals()) - bpy.ops.particle.particle_edit_toggle() - return particles + particles = psys.particles + bpy.ops.particle.particle_edit_toggle() + n = 0 + for (key, val, sub) in tokens: + if key == 'Particle': + parseParticle(particles[n], val, sub) + n += 1 + else: + for par in particles: + defaultKey(key, val, sub, 'par', [], globals(), locals()) + bpy.ops.particle.particle_edit_toggle() + return particles def parseParticle(par, args, tokens): - n = 0 - for (key, val, sub) in tokens: - if key == 'h': - h = par.hair[n] - h.location = eval(val[0]) - h.time = int(val[1]) - h.weight = float(val[2]) - n += 1 - elif key == 'location': - par.location = eval(val[0]) - return + n = 0 + for (key, val, sub) in tokens: + if key == 'h': + h = par.hair[n] + h.location = eval(val[0]) + h.time = int(val[1]) + h.weight = float(val[2]) + n += 1 + elif key == 'location': + par.location = eval(val[0]) + return # -# unpackList(list_of_tuples): +# unpackList(list_of_tuples): # def unpackList(list_of_tuples): - l = [] - for t in list_of_tuples: - l.extend(t) - return l + l = [] + for t in list_of_tuples: + l.extend(t) + return l # -# parseMesh (args, tokens): +# parseMesh (args, tokens): # def parseMesh (args, tokens): - global todo - if verbosity > 2: - print( "Parsing mesh %s" % args ) - - mename = args[0] - obname = args[1] - me = bpy.data.meshes.new(mename) - ob = createObject('MESH', obname, me, mename) - - verts = [] - edges = [] - faces = [] - vertsTex = [] - texFaces = [] - - for (key, val, sub) in tokens: - if key == 'Verts': - verts = parseVerts(sub) - elif key == 'Edges': - edges = parseEdges(sub) - elif key == 'Faces': - faces = parseFaces(sub) - - if faces: - me.from_pydata(verts, [], faces) - else: - me.from_pydata(verts, edges, []) - me.update() - linkObject(ob, me) - - mats = [] - for (key, val, sub) in tokens: - if key == 'Verts' or key == 'Edges' or key == 'Faces': - pass - elif key == 'MeshTextureFaceLayer': - parseUvTexture(val, sub, me) - elif key == 'MeshColorLayer': - parseVertColorLayer(val, sub, me) - elif key == 'VertexGroup': - parseVertexGroup(ob, me, val, sub) - elif key == 'ShapeKeys': - parseShapeKeys(ob, me, val, sub) - elif key == 'Material': - try: - mat = loadedData['Material'][val[0]] - except: - mat = None - if mat: - me.materials.append(mat) - else: - defaultKey(key, val, sub, "me", [], globals(), locals()) - - for (key, val, sub) in tokens: - if key == 'Faces': - parseFaces2(sub, me) - - for n,mat in enumerate(list(me.materials)): - print(n, mat) - return me - -# -# parseVerts(tokens): -# parseEdges(tokens): -# parseFaces(tokens): -# parseFaces2(tokens, me): + global todo + if verbosity > 2: + print( "Parsing mesh %s" % args ) + + mename = args[0] + obname = args[1] + me = bpy.data.meshes.new(mename) + ob = createObject('MESH', obname, me, mename) + + verts = [] + edges = [] + faces = [] + vertsTex = [] + texFaces = [] + + for (key, val, sub) in tokens: + if key == 'Verts': + verts = parseVerts(sub) + elif key == 'Edges': + edges = parseEdges(sub) + elif key == 'Faces': + faces = parseFaces(sub) + + if faces: + me.from_pydata(verts, [], faces) + else: + me.from_pydata(verts, edges, []) + me.update() + linkObject(ob, me) + + mats = [] + for (key, val, sub) in tokens: + if key == 'Verts' or key == 'Edges' or key == 'Faces': + pass + elif key == 'MeshTextureFaceLayer': + parseUvTexture(val, sub, me) + elif key == 'MeshColorLayer': + parseVertColorLayer(val, sub, me) + elif key == 'VertexGroup': + parseVertexGroup(ob, me, val, sub) + elif key == 'ShapeKeys': + parseShapeKeys(ob, me, val, sub) + elif key == 'Material': + try: + mat = loadedData['Material'][val[0]] + except: + mat = None + if mat: + me.materials.append(mat) + else: + defaultKey(key, val, sub, "me", [], globals(), locals()) + + for (key, val, sub) in tokens: + if key == 'Faces': + parseFaces2(sub, me) + + for n,mat in enumerate(list(me.materials)): + print(n, mat) + return me + +# +# parseVerts(tokens): +# parseEdges(tokens): +# parseFaces(tokens): +# parseFaces2(tokens, me): # def parseVerts(tokens): - verts = [] - for (key, val, sub) in tokens: - if key == 'v': - verts.append( (theScale*float(val[0]), theScale*float(val[1]), theScale*float(val[2])) ) - return verts + verts = [] + for (key, val, sub) in tokens: + if key == 'v': + verts.append( (theScale*float(val[0]), theScale*float(val[1]), theScale*float(val[2])) ) + return verts def parseEdges(tokens): - edges = [] - for (key, val, sub) in tokens: - if key == 'e': - edges.append((int(val[0]), int(val[1]))) - return edges - -def parseFaces(tokens): - faces = [] - for (key, val, sub) in tokens: - if key == 'f': - if len(val) == 3: - face = [int(val[0]), int(val[1]), int(val[2])] - elif len(val) == 4: - face = [int(val[0]), int(val[1]), int(val[2]), int(val[3])] - faces.append(face) - return faces - -def parseFaces2(tokens, me): - n = 0 - for (key, val, sub) in tokens: - if key == 'ft': - f = me.faces[n] - f.material_index = int(val[0]) - f.use_smooth = int(val[1]) - n += 1 - elif key == 'mn': - fn = int(val[0]) - mn = int(val[1]) - f = me.faces[fn] - f.material_index = mn - elif key == 'ftall': - mat = int(val[0]) - smooth = int(val[1]) - for f in me.faces: - f.material_index = mat - f.use_smooth = smooth - return - - -# -# parseUvTexture(args, tokens, me): -# parseUvTexData(args, tokens, uvdata): + edges = [] + for (key, val, sub) in tokens: + if key == 'e': + edges.append((int(val[0]), int(val[1]))) + return edges + +def parseFaces(tokens): + faces = [] + for (key, val, sub) in tokens: + if key == 'f': + if len(val) == 3: + face = [int(val[0]), int(val[1]), int(val[2])] + elif len(val) == 4: + face = [int(val[0]), int(val[1]), int(val[2]), int(val[3])] + faces.append(face) + return faces + +def parseFaces2(tokens, me): + n = 0 + for (key, val, sub) in tokens: + if key == 'ft': + f = me.faces[n] + f.material_index = int(val[0]) + f.use_smooth = int(val[1]) + n += 1 + elif key == 'mn': + fn = int(val[0]) + mn = int(val[1]) + f = me.faces[fn] + f.material_index = mn + elif key == 'ftall': + mat = int(val[0]) + smooth = int(val[1]) + for f in me.faces: + f.material_index = mat + f.use_smooth = smooth + return + + +# +# parseUvTexture(args, tokens, me): +# parseUvTexData(args, tokens, uvdata): # def parseUvTexture(args, tokens, me): - name = args[0] - me.uv_textures.new(name = name) - uvtex = me.uv_textures[-1] - loadedData['MeshTextureFaceLayer'][name] = uvtex - for (key, val, sub) in tokens: - if key == 'Data': - parseUvTexData(val, sub, uvtex.data) - else: - defaultKey(key, val, sub, "uvtex", [], globals(), locals()) - return + name = args[0] + me.uv_textures.new(name = name) + uvtex = me.uv_textures[-1] + loadedData['MeshTextureFaceLayer'][name] = uvtex + for (key, val, sub) in tokens: + if key == 'Data': + parseUvTexData(val, sub, uvtex.data) + else: + defaultKey(key, val, sub, "uvtex", [], globals(), locals()) + return def parseUvTexData(args, tokens, data): - n = 0 - for (key, val, sub) in tokens: - if key == 'vt': - data[n].uv1 = (float(val[0]), float(val[1])) - data[n].uv2 = (float(val[2]), float(val[3])) - data[n].uv3 = (float(val[4]), float(val[5])) - if len(val) > 6: - data[n].uv4 = (float(val[6]), float(val[7])) - n += 1 - else: - pass - #for i in range(n): - # defaultKey(key, val, sub, "data[i]", [], globals(), locals()) - return - -# -# parseVertColorLayer(args, tokens, me): -# parseVertColorData(args, tokens, data): + n = 0 + for (key, val, sub) in tokens: + if key == 'vt': + data[n].uv1 = (float(val[0]), float(val[1])) + data[n].uv2 = (float(val[2]), float(val[3])) + data[n].uv3 = (float(val[4]), float(val[5])) + if len(val) > 6: + data[n].uv4 = (float(val[6]), float(val[7])) + n += 1 + else: + pass + #for i in range(n): + # defaultKey(key, val, sub, "data[i]", [], globals(), locals()) + return + +# +# parseVertColorLayer(args, tokens, me): +# parseVertColorData(args, tokens, data): # def parseVertColorLayer(args, tokens, me): - name = args[0] - print("VertColorLayer", name) - vcol = me.vertex_colors.new(name) - #vcol.name = name - loadedData['MeshColorLayer'][name] = vcol - for (key, val, sub) in tokens: - if key == 'Data': - parseVertColorData(val, sub, vcol.data) - else: - defaultKey(key, val, sub, "vcol", [], globals(), locals()) - return + name = args[0] + print("VertColorLayer", name) + vcol = me.vertex_colors.new(name) + loadedData['MeshColorLayer'][name] = vcol + for (key, val, sub) in tokens: + if key == 'Data': + parseVertColorData(val, sub, vcol.data) + else: + defaultKey(key, val, sub, "vcol", [], globals(), locals()) + return def parseVertColorData(args, tokens, data): - n = 0 - for (key, val, sub) in tokens: - if key == 'cv': - data[n].color1 = eval(val[0]) - data[n].color2 = eval(val[1]) - data[n].color3 = eval(val[2]) - data[n].color4 = eval(val[3]) - n += 1 - return + n = 0 + for (key, val, sub) in tokens: + if key == 'cv': + data[n].color1 = eval(val[0]) + data[n].color2 = eval(val[1]) + data[n].color3 = eval(val[2]) + data[n].color4 = eval(val[3]) + n += 1 + return # -# parseVertexGroup(ob, me, args, tokens): +# parseVertexGroup(ob, me, args, tokens): # def parseVertexGroup(ob, me, args, tokens): - global toggle - if verbosity > 2: - print( "Parsing vertgroup %s" % args ) - grpName = args[0] - try: - res = eval(args[1]) - except: - res = True - if not res: - return - - if (toggle & T_Armature) or (grpName in ['Eye_L', 'Eye_R', 'Gums', 'Head', 'Jaw', 'Left', 'Middle', 'Right', 'Scalp']): - group = ob.vertex_groups.new(grpName) - loadedData['VertexGroup'][grpName] = group - for (key, val, sub) in tokens: - if key == 'wv': - ob.vertex_groups.assign( [int(val[0])], group, float(val[1]), 'REPLACE' ) - #ob.add_vertex_to_group( int(val[0]), group, float(val[1]), 'REPLACE') - return - - -# -# parseShapeKeys(ob, me, args, tokens): -# parseShapeKey(ob, me, args, tokens): -# addShapeKey(ob, name, vgroup, tokens): -# doShape(name): + global toggle + if verbosity > 2: + print( "Parsing vertgroup %s" % args ) + grpName = args[0] + try: + res = eval(args[1]) + except: + res = True + if not res: + return + + if (toggle & T_Armature) or (grpName in ['Eye_L', 'Eye_R', 'Gums', 'Head', 'Jaw', 'Left', 'Middle', 'Right', 'Scalp']): + group = ob.vertex_groups.new(grpName) + loadedData['VertexGroup'][grpName] = group + for (key, val, sub) in tokens: + if key == 'wv': + ob.vertex_groups.assign( [int(val[0])], group, float(val[1]), 'REPLACE' ) + return + + +# +# parseShapeKeys(ob, me, args, tokens): +# parseShapeKey(ob, me, args, tokens): +# addShapeKey(ob, name, vgroup, tokens): +# doShape(name): # def doShape(name): - if (toggle & T_Shape+T_Face) and (name == 'Basis'): - return True - else: - return (toggle & T_Face) + if (toggle & T_Shape+T_Face) and (name == 'Basis'): + return True + else: + return (toggle & T_Face) def parseShapeKeys(ob, me, args, tokens): - if bpy.context.object == None: - return - for (key, val, sub) in tokens: - if key == 'ShapeKey': - parseShapeKey(ob, me, val, sub) - elif key == 'AnimationData': - if me.shape_keys: - parseAnimationData(me.shape_keys, val, sub) - ob.active_shape_key_index = 0 - return + for (key, val, sub) in tokens: + if key == 'ShapeKey': + parseShapeKey(ob, me, val, sub) + elif key == 'AnimationData': + if me.shape_keys: + parseAnimationData(me.shape_keys, val, sub) + ob.active_shape_key_index = 0 + return def parseShapeKey(ob, me, args, tokens): - if verbosity > 0: - print( "Parsing ob %s shape %s" % (bpy.context.object, args[0] )) - name = args[0] - lr = args[1] - if invalid(args[2]): - return - - if lr == 'Sym' or toggle & T_Symm: - addShapeKey(ob, name, None, tokens) - elif lr == 'LR': - addShapeKey(ob, name+'_L', 'Left', tokens) - addShapeKey(ob, name+'_R', 'Right', tokens) - else: - raise NameError("ShapeKey L/R %s" % lr) - return + if verbosity > 2: + print( "Parsing ob %s shape %s" % (bpy.context.object, args[0] )) + name = args[0] + lr = args[1] + if invalid(args[2]): + return + + if lr == 'Sym' or toggle & T_Symm: + addShapeKey(ob, name, None, tokens) + elif lr == 'LR': + addShapeKey(ob, name+'_L', 'Left', tokens) + addShapeKey(ob, name+'_R', 'Right', tokens) + else: + raise NameError("ShapeKey L/R %s" % lr) + return def addShapeKey(ob, name, vgroup, tokens): - bpy.ops.object.shape_key_add(False) - skey = ob.active_shape_key - if name != 'Basis': - skey.relative_key = loadedData['ShapeKey']['Basis'] - skey.name = name - if vgroup: - skey.vertex_group = vgroup - loadedData['ShapeKey'][name] = skey + skey = ob.shape_key_add(name=name, from_mix=False) + if name != 'Basis': + skey.relative_key = loadedData['ShapeKey']['Basis'] + skey.name = name + if vgroup: + skey.vertex_group = vgroup + loadedData['ShapeKey'][name] = skey - for (key, val, sub) in tokens: - if key == 'sv': - index = int(val[0]) - pt = skey.data[index].co - pt[0] += theScale*float(val[1]) - pt[1] += theScale*float(val[2]) - pt[2] += theScale*float(val[3]) - else: - defaultKey(key, val, sub, "skey", [], globals(), locals()) + for (key, val, sub) in tokens: + if key == 'sv': + index = int(val[0]) + pt = skey.data[index].co + pt[0] += theScale*float(val[1]) + pt[1] += theScale*float(val[2]) + pt[2] += theScale*float(val[3]) + else: + defaultKey(key, val, sub, "skey", [], globals(), locals()) - return + return - + # -# parseArmature (obName, args, tokens) +# parseArmature (obName, args, tokens) # def parseArmature (args, tokens): - global toggle - if verbosity > 2: - print( "Parsing armature %s" % args ) - - amtname = args[0] - obname = args[1] - mode = args[2] - - if mode == 'Rigify': - toggle |= T_Rigify - return parseRigify(amtname, obname, tokens) - - toggle &= ~T_Rigify - amt = bpy.data.armatures.new(amtname) - ob = createObject('ARMATURE', obname, amt, amtname) - - linkObject(ob, amt) - print("Linked") - - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.mode_set(mode='EDIT') - - heads = {} - tails = {} - for (key, val, sub) in tokens: - if key == 'Bone': - bname = val[0] - if not invalid(val[1]): - bone = amt.edit_bones.new(bname) - parseBone(bone, amt, sub, heads, tails) - loadedData['Bone'][bname] = bone - else: - defaultKey(key, val, sub, "amt", ['MetaRig'], globals(), locals()) - bpy.ops.object.mode_set(mode='OBJECT') - return amt - -# -# parseRigify(amtname, obname, tokens): -# - -def parseRigify(amtname, obname, tokens): - (key,val,sub) = tokens[0] - if key != 'MetaRig': - raise NameError("Expected MetaRig") - typ = val[0] - if typ == "human": - bpy.ops.object.armature_human_advanced_add() - else: - bpy.ops.pose.metarig_sample_add(type = typ) - ob = bpy.context.scene.objects.active - amt = ob.data - loadedData['Rigify'][obname] = ob - loadedData['Armature'][amtname] = amt - loadedData['Object'][obname] = ob - print("Rigify object", ob, amt) - - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.mode_set(mode='EDIT') - - heads = {} - tails = {} - for (bname, bone) in amt.edit_bones.items(): - heads[bname] = 10*theScale*bone.head - tails[bname] = 10*theScale*bone.tail - - for (key, val, sub) in tokens: - if key == 'Bone': - bname = val[0] - print("Bone", bname) - try: - bone = amt.edit_bones[bname] - except: - print("Did not find bone %s" % bname) - bone = None - print(" -> ", bone) - if bone: - parseBone(bone, amt, sub, heads, tails) - else: - defaultKey(key, val, sub, "amt", ['MetaRig'], globals(), locals()) - bpy.ops.object.mode_set(mode='OBJECT') - return amt - -# -# parseBone(bone, amt, tokens, heads, tails): + global toggle + if verbosity > 2: + print( "Parsing armature %s" % args ) + + amtname = args[0] + obname = args[1] + mode = args[2] + + if mode == 'Rigify': + toggle |= T_Rigify + return parseRigify(amtname, obname, tokens) + + toggle &= ~T_Rigify + amt = bpy.data.armatures.new(amtname) + ob = createObject('ARMATURE', obname, amt, amtname) + + linkObject(ob, amt) + print("Linked") + + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='EDIT') + + heads = {} + tails = {} + for (key, val, sub) in tokens: + if key == 'Bone': + bname = val[0] + if not invalid(val[1]): + bone = amt.edit_bones.new(bname) + parseBone(bone, amt, sub, heads, tails) + loadedData['Bone'][bname] = bone + else: + defaultKey(key, val, sub, "amt", ['MetaRig'], globals(), locals()) + bpy.ops.object.mode_set(mode='OBJECT') + return amt + +# +# parseRigify(amtname, obname, tokens): +# + +def parseRigify(amtname, obname, tokens): + (key,val,sub) = tokens[0] + if key != 'MetaRig': + raise NameError("Expected MetaRig") + typ = val[0] + if typ == "human": + bpy.ops.object.armature_human_advanced_add() + else: + bpy.ops.pose.metarig_sample_add(type = typ) + ob = bpy.context.scene.objects.active + amt = ob.data + loadedData['Rigify'][obname] = ob + loadedData['Armature'][amtname] = amt + loadedData['Object'][obname] = ob + print("Rigify object", ob, amt) + + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='EDIT') + + heads = {} + tails = {} + for (bname, bone) in amt.edit_bones.items(): + heads[bname] = 10*theScale*bone.head + tails[bname] = 10*theScale*bone.tail + + for (key, val, sub) in tokens: + if key == 'Bone': + bname = val[0] + print("Bone", bname) + try: + bone = amt.edit_bones[bname] + except: + print("Did not find bone %s" % bname) + bone = None + print(" -> ", bone) + if bone: + parseBone(bone, amt, sub, heads, tails) + else: + defaultKey(key, val, sub, "amt", ['MetaRig'], globals(), locals()) + bpy.ops.object.mode_set(mode='OBJECT') + return amt + +# +# parseBone(bone, amt, tokens, heads, tails): # def parseBone(bone, amt, tokens, heads, tails): - global todo + global todo - for (key, val, sub) in tokens: - if key == "head": - bone.head = (theScale*float(val[0]), theScale*float(val[1]), theScale*float(val[2])) - elif key == "tail": - bone.tail = (theScale*float(val[0]), theScale*float(val[1]), theScale*float(val[2])) - #elif key == 'restrict_select': - # pass - elif key == 'hide' and val[0] == 'True': - name = bone.name - ''' - #bpy.ops.object.mode_set(mode='OBJECT') - pbone = amt.bones[name] - pbone.hide = True - print("Hide", pbone, pbone.hide) - #bpy.ops.object.mode_set(mode='EDIT') - ''' - else: - defaultKey(key, val, sub, "bone", [], globals(), locals()) + for (key, val, sub) in tokens: + if key == "head": + bone.head = (theScale*float(val[0]), theScale*float(val[1]), theScale*float(val[2])) + elif key == "tail": + bone.tail = (theScale*float(val[0]), theScale*float(val[1]), theScale*float(val[2])) + #elif key == 'restrict_select': + # pass + elif key == 'hide' and val[0] == 'True': + name = bone.name + ''' + #bpy.ops.object.mode_set(mode='OBJECT') + pbone = amt.bones[name] + pbone.hide = True + print("Hide", pbone, pbone.hide) + #bpy.ops.object.mode_set(mode='EDIT') + ''' + else: + defaultKey(key, val, sub, "bone", [], globals(), locals()) - return bone + return bone # -# parsePose (args, tokens): +# parsePose (args, tokens): # def parsePose (args, tokens): - global todo - if toggle & T_Rigify: - return - name = args[0] - ob = loadedData['Object'][name] - bpy.context.scene.objects.active = ob - bpy.ops.object.mode_set(mode='POSE') - pbones = ob.pose.bones - nGrps = 0 - for (key, val, sub) in tokens: - if key == 'Posebone': - parsePoseBone(pbones, ob, val, sub) - elif key == 'BoneGroup': - parseBoneGroup(ob.pose, nGrps, val, sub) - nGrps += 1 - elif key == 'SetProp': - bone = val[0] - prop = val[1] - value = eval(val[2]) - pb = pbones[bone] - print("Setting", pb, prop, val) - pb[prop] = value - print("Prop set", pb[prop]) - else: - defaultKey(key, val, sub, "ob.pose", [], globals(), locals()) - bpy.ops.object.mode_set(mode='OBJECT') - return ob - - -# -# parsePoseBone(pbones, args, tokens): -# parseArray(data, exts, args): + global todo + if toggle & T_Rigify: + return + name = args[0] + ob = loadedData['Object'][name] + bpy.context.scene.objects.active = ob + bpy.ops.object.mode_set(mode='POSE') + pbones = ob.pose.bones + nGrps = 0 + for (key, val, sub) in tokens: + if key == 'Posebone': + parsePoseBone(pbones, ob, val, sub) + elif key == 'BoneGroup': + parseBoneGroup(ob.pose, nGrps, val, sub) + nGrps += 1 + elif key == 'SetProp': + bone = val[0] + prop = val[1] + value = eval(val[2]) + pb = pbones[bone] + print("Setting", pb, prop, val) + pb[prop] = value + print("Prop set", pb[prop]) + else: + defaultKey(key, val, sub, "ob.pose", [], globals(), locals()) + bpy.ops.object.mode_set(mode='OBJECT') + return ob + + +# +# parsePoseBone(pbones, args, tokens): +# parseArray(data, exts, args): # def parseBoneGroup(pose, nGrps, args, tokens): - global todo - print( "Parsing bonegroup %s" % args ) - name = args[0] - bpy.ops.pose.group_add() - print(dir(pose.bone_groups)) - bg = pose.bone_groups.active - print("Created", bg) - loadedData['BoneGroup'][name] = bg - for (key, val, sub) in tokens: - print(key,val) - defaultKey(key, val, sub, "bg", [], globals(), locals()) - return + global todo + print( "Parsing bonegroup %s" % args ) + name = args[0] + bpy.ops.pose.group_add() + print(dir(pose.bone_groups)) + bg = pose.bone_groups.active + print("Created", bg) + loadedData['BoneGroup'][name] = bg + for (key, val, sub) in tokens: + defaultKey(key, val, sub, "bg", [], globals(), locals()) + return def parsePoseBone(pbones, ob, args, tokens): - global todo - if invalid(args[1]): - return - name = args[0] - pb = pbones[name] - amt = ob.data - - # Make posebone active - don't know how to do this in pose mode - bpy.ops.object.mode_set(mode='OBJECT') - amt.bones.active = amt.bones[name] - bpy.ops.object.mode_set(mode='POSE') - - for (key, val, sub) in tokens: - if key == 'Constraint': - cns = parseConstraint(pb.constraints, val, sub) - elif key == 'bpyops': - bpy.ops.object.mode_set(mode='OBJECT') - amt.bones.active = amt.bones[name] - ob.constraints.active = cns - expr = "bpy.ops.%s" % val[0] - # print(expr) - exec(expr) - bpy.ops.object.mode_set(mode='POSE') - elif key == 'ik_dof': - parseArray(pb, ["ik_dof_x", "ik_dof_y", "ik_dof_z"], val) - elif key == 'ik_limit': - parseArray(pb, ["ik_limit_x", "ik_limit_y", "ik_limit_z"], val) - elif key == 'ik_max': - parseArray(pb, ["ik_max_x", "ik_max_y", "ik_max_z"], val) - elif key == 'ik_min': - parseArray(pb, ["ik_min_x", "ik_min_y", "ik_min_z"], val) - elif key == 'ik_stiffness': - parseArray(pb, ["ik_stiffness_x", "ik_stiffness_y", "ik_stiffness_z"], val) - elif key == 'hide': - #bpy.ops.object.mode_set(mode='OBJECT') - amt.bones[name].hide = eval(val[0]) - #bpy.ops.object.mode_set(mode='POSE') - - else: - defaultKey(key, val, sub, "pb", [], globals(), locals()) - #print("pb %s done" % name) - return + global todo + if invalid(args[1]): + return + name = args[0] + pb = pbones[name] + amt = ob.data + + # Make posebone active - don't know how to do this in pose mode + bpy.ops.object.mode_set(mode='OBJECT') + amt.bones.active = amt.bones[name] + bpy.ops.object.mode_set(mode='POSE') + + for (key, val, sub) in tokens: + if key == 'Constraint': + cns = parseConstraint(pb.constraints, val, sub) + elif key == 'bpyops': + bpy.ops.object.mode_set(mode='OBJECT') + amt.bones.active = amt.bones[name] + ob.constraints.active = cns + expr = "bpy.ops.%s" % val[0] + # print(expr) + exec(expr) + bpy.ops.object.mode_set(mode='POSE') + elif key == 'ik_dof': + parseArray(pb, ["ik_dof_x", "ik_dof_y", "ik_dof_z"], val) + elif key == 'ik_limit': + parseArray(pb, ["ik_limit_x", "ik_limit_y", "ik_limit_z"], val) + elif key == 'ik_max': + parseArray(pb, ["ik_max_x", "ik_max_y", "ik_max_z"], val) + elif key == 'ik_min': + parseArray(pb, ["ik_min_x", "ik_min_y", "ik_min_z"], val) + elif key == 'ik_stiffness': + parseArray(pb, ["ik_stiffness_x", "ik_stiffness_y", "ik_stiffness_z"], val) + elif key == 'hide': + #bpy.ops.object.mode_set(mode='OBJECT') + amt.bones[name].hide = eval(val[0]) + #bpy.ops.object.mode_set(mode='POSE') + + else: + defaultKey(key, val, sub, "pb", [], globals(), locals()) + #print("pb %s done" % name) + return def parseArray(data, exts, args): - n = 1 - for ext in exts: - expr = "data.%s = %s" % (ext, args[n]) - # print(expr) - exec(expr) - n += 1 - return - + n = 1 + for ext in exts: + expr = "data.%s = %s" % (ext, args[n]) + # print(expr) + exec(expr) + n += 1 + return + # -# parseConstraint(constraints, args, tokens) +# parseConstraint(constraints, args, tokens) # def parseConstraint(constraints, args, tokens): - if invalid(args[2]): - return None - cns = constraints.new(args[1]) - #bpy.ops.pose.constraint_add(type=args[1]) - #cns = pb.constraints[-1] + if invalid(args[2]): + return None + cns = constraints.new(args[1]) + #bpy.ops.pose.constraint_add(type=args[1]) + #cns = pb.constraints[-1] - cns.name = args[0] - #print("cns", cns.name) - for (key,val,sub) in tokens: - if key == 'invert': - parseArray(cns, ["invert_x", "invert_y", "invert_z"], val) - elif key == 'use': - parseArray(cns, ["use_x", "use_y", "use_z"], val) - elif key == 'pos_lock': - parseArray(cns, ["lock_location_x", "lock_location_y", "lock_location_z"], val) - elif key == 'rot_lock': - parseArray(cns, ["lock_rotation_x", "lock_rotation_y", "lock_rotation_z"], val) - else: - defaultKey(key, val, sub, "cns", [], globals(), locals()) + cns.name = args[0] + #print("cns", cns.name) + for (key,val,sub) in tokens: + if key == 'invert': + parseArray(cns, ["invert_x", "invert_y", "invert_z"], val) + elif key == 'use': + parseArray(cns, ["use_x", "use_y", "use_z"], val) + elif key == 'pos_lock': + parseArray(cns, ["lock_location_x", "lock_location_y", "lock_location_z"], val) + elif key == 'rot_lock': + parseArray(cns, ["lock_rotation_x", "lock_rotation_y", "lock_rotation_z"], val) + else: + defaultKey(key, val, sub, "cns", [], globals(), locals()) - #print("cns %s done" % cns.name) - return cns + #print("cns %s done" % cns.name) + return cns # -# parseCurve (args, tokens): -# parseSpline(cu, args, tokens): -# parseBezier(spline, n, args, tokens): +# parseCurve (args, tokens): +# parseSpline(cu, args, tokens): +# parseBezier(spline, n, args, tokens): # def parseCurve (args, tokens): - global todo - if verbosity > 2: - print( "Parsing curve %s" % args ) - bpy.ops.object.add(type='CURVE') - cu = setObjectAndData(args, 'Curve') - - for (key, val, sub) in tokens: - if key == 'Spline': - parseSpline(cu, val, sub) - else: - defaultKey(key, val, sub, "cu", [], globals(), locals()) - return + global todo + if verbosity > 2: + print( "Parsing curve %s" % args ) + bpy.ops.object.add(type='CURVE') + cu = setObjectAndData(args, 'Curve') + + for (key, val, sub) in tokens: + if key == 'Spline': + parseSpline(cu, val, sub) + else: + defaultKey(key, val, sub, "cu", [], globals(), locals()) + return def parseTextCurve (args, tokens): - global todo - if verbosity > 2: - print( "Parsing text curve %s" % args ) - bpy.ops.object.text_add() - txt = setObjectAndData(args, 'Text') - - for (key, val, sub) in tokens: - if key == 'Spline': - parseSpline(txt, val, sub) - elif key == 'BodyFormat': - parseCollection(txt.body_format, sub, []) - elif key == 'EditFormat': - parseDefault(txt.edit_format, sub, {}, []) - elif key == 'Font': - parseDefault(txt.font, sub, {}, []) - elif key == 'TextBox': - parseCollection(txt.body_format, sub, []) - else: - defaultKey(key, val, sub, "txt", [], globals(), locals()) - return + global todo + if verbosity > 2: + print( "Parsing text curve %s" % args ) + bpy.ops.object.text_add() + txt = setObjectAndData(args, 'Text') + + for (key, val, sub) in tokens: + if key == 'Spline': + parseSpline(txt, val, sub) + elif key == 'BodyFormat': + parseCollection(txt.body_format, sub, []) + elif key == 'EditFormat': + parseDefault(txt.edit_format, sub, {}, []) + elif key == 'Font': + parseDefault(txt.font, sub, {}, []) + elif key == 'TextBox': + parseCollection(txt.body_format, sub, []) + else: + defaultKey(key, val, sub, "txt", [], globals(), locals()) + return def parseSpline(cu, args, tokens): - typ = args[0] - spline = cu.splines.new(typ) - nPointsU = int(args[1]) - nPointsV = int(args[2]) - #spline.point_count_u = nPointsU - #spline.point_count_v = nPointsV - if typ == 'BEZIER' or typ == 'BSPLINE': - spline.bezier_points.add(nPointsU) - else: - spline.points.add(nPointsU) - - n = 0 - for (key, val, sub) in tokens: - if key == 'bz': - parseBezier(spline.bezier_points[n], val, sub) - n += 1 - elif key == 'pt': - parsePoint(spline.points[n], val, sub) - n += 1 - else: - defaultKey(key, val, sub, "spline", [], globals(), locals()) - return - + typ = args[0] + spline = cu.splines.new(typ) + nPointsU = int(args[1]) + nPointsV = int(args[2]) + #spline.point_count_u = nPointsU + #spline.point_count_v = nPointsV + if typ == 'BEZIER' or typ == 'BSPLINE': + spline.bezier_points.add(nPointsU) + else: + spline.points.add(nPointsU) + + n = 0 + for (key, val, sub) in tokens: + if key == 'bz': + parseBezier(spline.bezier_points[n], val, sub) + n += 1 + elif key == 'pt': + parsePoint(spline.points[n], val, sub) + n += 1 + else: + defaultKey(key, val, sub, "spline", [], globals(), locals()) + return + def parseBezier(bez, args, tokens): - bez.co = eval(args[0]) - bez.co = theScale*bez.co - bez.handle1 = eval(args[1]) - bez.handle1_type = args[2] - bez.handle2 = eval(args[3]) - bez.handle2_type = args[4] - return + bez.co = eval(args[0]) + bez.co = theScale*bez.co + bez.handle1 = eval(args[1]) + bez.handle1_type = args[2] + bez.handle2 = eval(args[3]) + bez.handle2_type = args[4] + return def parsePoint(pt, args, tokens): - pt.co = eval(args[0]) - pt.co = theScale*pt.co - return + pt.co = eval(args[0]) + pt.co = theScale*pt.co + return # -# parseLattice (args, tokens): +# parseLattice (args, tokens): # def parseLattice (args, tokens): - global todo - if verbosity > 2: - print( "Parsing lattice %s" % args ) - bpy.ops.object.add(type='LATTICE') - lat = setObjectAndData(args, 'Lattice') - for (key, val, sub) in tokens: - if key == 'Points': - parseLatticePoints(val, sub, lat.points) - else: - defaultKey(key, val, sub, "lat", [], globals(), locals()) - return + global todo + if verbosity > 2: + print( "Parsing lattice %s" % args ) + bpy.ops.object.add(type='LATTICE') + lat = setObjectAndData(args, 'Lattice') + for (key, val, sub) in tokens: + if key == 'Points': + parseLatticePoints(val, sub, lat.points) + else: + defaultKey(key, val, sub, "lat", [], globals(), locals()) + return def parseLatticePoints(args, tokens, points): - global todo - n = 0 - for (key, val, sub) in tokens: - if key == 'pt': - v = points[n].co - (x,y,z) = eval(val[0]) - v.x = theScale*x - v.y = theScale*y - v.z = theScale*z + global todo + n = 0 + for (key, val, sub) in tokens: + if key == 'pt': + v = points[n].co + (x,y,z) = eval(val[0]) + v.x = theScale*x + v.y = theScale*y + v.z = theScale*z - v = points[n].deformed_co - (x,y,z) = eval(val[1]) - v.x = theScale*x - v.y = theScale*y - v.z = theScale*z + v = points[n].deformed_co + (x,y,z) = eval(val[1]) + v.x = theScale*x + v.y = theScale*y + v.z = theScale*z - n += 1 - return + n += 1 + return # -# parseLamp (args, tokens): -# parseFalloffCurve(focu, args, tokens): +# parseLamp (args, tokens): +# parseFalloffCurve(focu, args, tokens): # def parseLamp (args, tokens): - global todo - if verbosity > 2: - print( "Parsing lamp %s" % args ) - bpy.ops.object.add(type='LAMP') - lamp = setObjectAndData(args, 'Lamp') - for (key, val, sub) in tokens: - if key == 'FalloffCurve': - parseFalloffCurve(lamp.falloff_curve, val, sub) - else: - defaultKey(key, val, sub, "lamp", [], globals(), locals()) - return + global todo + if verbosity > 2: + print( "Parsing lamp %s" % args ) + bpy.ops.object.add(type='LAMP') + lamp = setObjectAndData(args, 'Lamp') + for (key, val, sub) in tokens: + if key == 'FalloffCurve': + parseFalloffCurve(lamp.falloff_curve, val, sub) + else: + defaultKey(key, val, sub, "lamp", [], globals(), locals()) + return def parseFalloffCurve(focu, args, tokens): - return + return # -# parseGroup (args, tokens): -# parseGroupObjects(args, tokens, grp): +# parseGroup (args, tokens): +# parseGroupObjects(args, tokens, grp): # def parseGroup (args, tokens): - global todo - if verbosity > 2: - print( "Parsing group %s" % args ) - - grpName = args[0] - grp = bpy.data.groups.new(grpName) - loadedData['Group'][grpName] = grp - for (key, val, sub) in tokens: - if key == 'Objects': - parseGroupObjects(val, sub, grp) - else: - defaultKey(key, val, sub, "grp", [], globals(), locals()) - return + global todo + if verbosity > 2: + print( "Parsing group %s" % args ) + + grpName = args[0] + grp = bpy.data.groups.new(grpName) + loadedData['Group'][grpName] = grp + for (key, val, sub) in tokens: + if key == 'Objects': + parseGroupObjects(val, sub, grp) + else: + defaultKey(key, val, sub, "grp", [], globals(), locals()) + return def parseGroupObjects(args, tokens, grp): - global todo - for (key, val, sub) in tokens: - if key == 'ob': - try: - ob = loadedData['Object'][val[0]] - grp.objects.link(ob) - except: - pass - return + global todo + for (key, val, sub) in tokens: + if key == 'ob': + try: + ob = loadedData['Object'][val[0]] + grp.objects.link(ob) + except: + pass + return # -# parseWorld (args, tokens): +# parseWorld (args, tokens): # def parseWorld (args, tokens): - global todo - if verbosity > 2: - print( "Parsing world %s" % args ) - world = bpy.context.scene.world - for (key, val, sub) in tokens: - if key == 'Lighting': - parseDefault(world.lighting, sub, {}, []) - elif key == 'Mist': - parseDefault(world.mist, sub, {}, []) - elif key == 'Stars': - parseDefault(world.stars, sub, {}, []) - else: - defaultKey(key, val, sub, "world", [], globals(), locals()) - return - -# -# parseScene (args, tokens): -# parseRenderSettings(render, args, tokens): -# parseToolSettings(tool, args, tokens): + global todo + if verbosity > 2: + print( "Parsing world %s" % args ) + world = bpy.context.scene.world + for (key, val, sub) in tokens: + if key == 'Lighting': + parseDefault(world.lighting, sub, {}, []) + elif key == 'Mist': + parseDefault(world.mist, sub, {}, []) + elif key == 'Stars': + parseDefault(world.stars, sub, {}, []) + else: + defaultKey(key, val, sub, "world", [], globals(), locals()) + return + +# +# parseScene (args, tokens): +# parseRenderSettings(render, args, tokens): +# parseToolSettings(tool, args, tokens): # def parseScene (args, tokens): - global todo - if verbosity > 2: - print( "Parsing scene %s" % args ) - scn = bpy.context.scene - for (key, val, sub) in tokens: - if key == 'NodeTree': - scn.use_nodes = True - parseNodeTree(scn, val, sub) - elif key == 'GameData': - parseDefault(scn.game_data, sub, {}, []) - elif key == 'KeyingSet': - pass - #parseDefault(scn.keying_sets, sub, {}, []) - elif key == 'ObjectBase': - pass - #parseDefault(scn.bases, sub, {}, []) - elif key == 'RenderSettings': - parseRenderSettings(scn.render, sub, []) - elif key == 'ToolSettings': - subkeys = {'ImagePaint' : "image_paint", - 'Sculpt' : "sculpt", - 'VertexPaint' : "vertex_paint", - 'WeightPaint' : "weight_paint" } - parseDefault(scn.tool_settings, sub, subkeys, []) - elif key == 'UnitSettings': - parseDefault(scn.unit_settings, sub, {}, []) - else: - defaultKey(key, val, sub, "scn", [], globals(), locals()) - return + global todo + if verbosity > 2: + print( "Parsing scene %s" % args ) + scn = bpy.context.scene + for (key, val, sub) in tokens: + if key == 'NodeTree': + scn.use_nodes = True + parseNodeTree(scn, val, sub) + elif key == 'GameData': + parseDefault(scn.game_data, sub, {}, []) + elif key == 'KeyingSet': + pass + #parseDefault(scn.keying_sets, sub, {}, []) + elif key == 'ObjectBase': + pass + #parseDefault(scn.bases, sub, {}, []) + elif key == 'RenderSettings': + parseRenderSettings(scn.render, sub, []) + elif key == 'ToolSettings': + subkeys = {'ImagePaint' : "image_paint", + 'Sculpt' : "sculpt", + 'VertexPaint' : "vertex_paint", + 'WeightPaint' : "weight_paint" } + parseDefault(scn.tool_settings, sub, subkeys, []) + elif key == 'UnitSettings': + parseDefault(scn.unit_settings, sub, {}, []) + else: + defaultKey(key, val, sub, "scn", [], globals(), locals()) + return def parseRenderSettings(render, args, tokens): - global todo - if verbosity > 2: - print( "Parsing RenderSettings %s" % args ) - for (key, val, sub) in tokens: - if key == 'Layer': - pass - #parseDefault(scn.layers, sub, []) - else: - defaultKey(key, val, sub, "render", [], globals(), locals()) - return + global todo + if verbosity > 2: + print( "Parsing RenderSettings %s" % args ) + for (key, val, sub) in tokens: + if key == 'Layer': + pass + #parseDefault(scn.layers, sub, []) + else: + defaultKey(key, val, sub, "render", [], globals(), locals()) + return # -# postProcess() +# postProcess() # def postProcess(): - if not toggle & T_MHX: - return - try: - ob = loadedData['Object']['HumanMesh'] - except: - ob = None - if toggle & T_Diamond == 0 and ob: - deleteDiamonds(ob) - if toggle & T_Rigify and False: - for rig in loadedData['Rigify'].values(): - bpy.context.scene.objects.active = rig - print("Rigify", rig) - bpy.ops.pose.metarig_generate() - print("Metarig generated") - #bpy.context.scene.objects.unlink(rig) - - rig = bpy.context.scene.objects.active - print("Rigged", rig, bpy.context.object) - ob = loadedData['Object']['HumanMesh'] - mod = ob.modifiers[0] - print(ob, mod, mod.object) - mod.object = rig - print("Rig changed", mod.object) - return - -# -# deleteDiamonds(ob) -# Delete joint diamonds in main mesh + if not toggle & T_MHX: + return + try: + ob = loadedData['Object']['HumanMesh'] + except: + ob = None + if toggle & T_Diamond == 0 and ob: + deleteDiamonds(ob) + if toggle & T_Rigify and False: + for rig in loadedData['Rigify'].values(): + bpy.context.scene.objects.active = rig + print("Rigify", rig) + bpy.ops.pose.metarig_generate() + print("Metarig generated") + #bpy.context.scene.objects.unlink(rig) + + rig = bpy.context.scene.objects.active + print("Rigged", rig, bpy.context.object) + ob = loadedData['Object']['HumanMesh'] + mod = ob.modifiers[0] + print(ob, mod, mod.object) + mod.object = rig + print("Rig changed", mod.object) + return + +# +# deleteDiamonds(ob) +# Delete joint diamonds in main mesh # def deleteDiamonds(ob): - bpy.context.scene.objects.active = ob - if not bpy.context.object: - return - print("Delete diamonds in %s" % bpy.context.object) - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.object.mode_set(mode='OBJECT') - me = ob.data - for f in me.faces: - if len(f.vertices) < 4: - for vn in f.vertices: - me.vertices[vn].select = True - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.delete(type='VERT') - bpy.ops.object.mode_set(mode='OBJECT') - return - - -# -# parseProcess(args, tokens): -# applyTransform(objects, rig, parents): + bpy.context.scene.objects.active = ob + if not bpy.context.object: + return + print("Delete diamonds in %s" % bpy.context.object) + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.select_all(action='DESELECT') + bpy.ops.object.mode_set(mode='OBJECT') + me = ob.data + for f in me.faces: + if len(f.vertices) < 4: + for vn in f.vertices: + me.vertices[vn].select = True + bpy.ops.object.mode_set(mode='EDIT') + 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): - 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 = mathutils.Matrix.Rotation(angle, 4, axis) - try: - pb = pbones[val[0]] - prod = pb.matrix_basis * mat - for i in range(4): - for j in range(4): - pb.matrix_local[i][j] = prod[i][j] - except: - print("No bone "+val[0]) - pass - elif key == 'Snap': - try: - eb = ebones[val[0]] - except: - eb = None - tb = ebones[val[1]] - typ = val[2] - if eb == 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: - raise NameError("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 + 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 = mathutils.Matrix.Rotation(angle, 4, axis) + try: + pb = pbones[val[0]] + prod = pb.matrix_local * mat + for i in range(4): + for j in range(4): + pb.matrix_local[i][j] = prod[i][j] + except: + print("No bone "+val[0]) + pass + elif key == 'Snap': + try: + eb = ebones[val[0]] + except: + eb = None + tb = ebones[val[1]] + typ = val[2] + if eb == 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: + raise NameError("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') + 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.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 + bpy.ops.object.mode_set(mode='OBJECT') + return # -# defaultKey(ext, args, tokens, var, exclude, glbals, lcals): +# defaultKey(ext, args, tokens, var, exclude, glbals, lcals): # def defaultKey(ext, args, tokens, var, exclude, glbals, lcals): - global todo - - if ext == 'Property': - try: - expr = "%s['%s'] = %s" % (var, args[0], args[1]) - except: - expr = None - print("Property", expr) - if expr: - exec(expr, glbals, lcals) - return - - nvar = "%s.%s" % (var, ext) - #print(ext) - if ext in exclude: - return - #print("D", nvar) - - if len(args) == 0: - raise NameError("Key length 0: %s" % ext) - - rnaType = args[0] - if rnaType == 'Add': - print("*** Cannot Add yet ***") - return - - elif rnaType == 'Refer': - typ = args[1] - name = args[2] - data = "loadedData['%s']['%s']" % (typ, name) - - elif rnaType == 'Struct' or rnaType == 'Define': - typ = args[1] - name = args[2] - try: - data = eval(nvar, glbals, lcals) - except: - data = None - # print("Old structrna", nvar, data) - - if data == None: - try: - creator = args[3] - except: - creator = None - # print("Creator", creator, eval(var,glbals,lcals)) - - try: - rna = eval(var,glbals,lcals) - data = eval(creator) - except: - data = None - # print("New struct", nvar, typ, data) - - if rnaType == 'Define': - loadedData[typ][name] = data - - if data: - for (key, val, sub) in tokens: - defaultKey(key, val, sub, "data", [], globals(), locals()) - - print("Struct done", nvar) - return - - elif rnaType == 'PropertyRNA': - raise NameError("PropertyRNA!") - #print("PropertyRNA ", ext, var) - for (key, val, sub) in tokens: - defaultKey(ext, val, sub, nvar, [], glbals, lcals) - return - - elif rnaType == 'Array': - for n in range(1, len(args)): - expr = "%s[%d] = %s" % (nvar, n-1, args[n]) - exec(expr, glbals, lcals) - if len(args) > 0: - expr = "%s[0] = %s" % (nvar, args[1]) - exec(expr, glbals, lcals) - return - - elif rnaType == 'List': - data = [] - for (key, val, sub) in tokens: - elt = eval(val[1], glbals, lcals) - data.append(elt) - - elif rnaType == 'Matrix': - return - i = 0 - n = len(tokens) - for (key, val, sub) in tokens: - if key == 'row': - for j in range(n): - expr = "%s[%d][%d] = %g" % (nvar, i, j, float(val[j])) - exec(expr, glbals, lcals) - i += 1 - return - - else: - try: - data = loadedData[rnaType][args[1]] - #print("From loaded", rnaType, args[1], data) - return data - except: - data = rnaType - - #print(var, ext, data) - expr = "%s = %s" % (nvar, data) - try: - exec(expr, glbals, lcals) - except: - pushOnTodoList(var, expr, glbals, lcals) - return + global todo + + if ext == 'Property': + try: + expr = "%s['%s'] = %s" % (var, args[0], args[1]) + except: + expr = None + # print("Property", expr) + if expr: + exec(expr, glbals, lcals) + return + + nvar = "%s.%s" % (var, ext) + #print(ext) + if ext in exclude: + return + #print("D", nvar) + + if len(args) == 0: + raise NameError("Key length 0: %s" % ext) + + rnaType = args[0] + if rnaType == 'Add': + print("*** Cannot Add yet ***") + return + + elif rnaType == 'Refer': + typ = args[1] + name = args[2] + data = "loadedData['%s']['%s']" % (typ, name) + + elif rnaType == 'Struct' or rnaType == 'Define': + typ = args[1] + name = args[2] + try: + data = eval(nvar, glbals, lcals) + except: + data = None + # print("Old structrna", nvar, data) + + if data == None: + try: + creator = args[3] + except: + creator = None + # print("Creator", creator, eval(var,glbals,lcals)) + + try: + rna = eval(var,glbals,lcals) + data = eval(creator) + except: + data = None + # print("New struct", nvar, typ, data) + + if rnaType == 'Define': + loadedData[typ][name] = data + + if data: + for (key, val, sub) in tokens: + defaultKey(key, val, sub, "data", [], globals(), locals()) + + print("Struct done", nvar) + return + + elif rnaType == 'PropertyRNA': + raise NameError("PropertyRNA!") + #print("PropertyRNA ", ext, var) + for (key, val, sub) in tokens: + defaultKey(ext, val, sub, nvar, [], glbals, lcals) + return + + elif rnaType == 'Array': + for n in range(1, len(args)): + expr = "%s[%d] = %s" % (nvar, n-1, args[n]) + exec(expr, glbals, lcals) + if len(args) > 0: + expr = "%s[0] = %s" % (nvar, args[1]) + exec(expr, glbals, lcals) + return + + elif rnaType == 'List': + data = [] + for (key, val, sub) in tokens: + elt = eval(val[1], glbals, lcals) + data.append(elt) + + elif rnaType == 'Matrix': + return + i = 0 + n = len(tokens) + for (key, val, sub) in tokens: + if key == 'row': + for j in range(n): + expr = "%s[%d][%d] = %g" % (nvar, i, j, float(val[j])) + exec(expr, glbals, lcals) + i += 1 + return + + else: + try: + data = loadedData[rnaType][args[1]] + #print("From loaded", rnaType, args[1], data) + return data + except: + data = rnaType + + #print(var, ext, data) + expr = "%s = %s" % (nvar, data) + try: + exec(expr, glbals, lcals) + except: + pushOnTodoList(var, expr, glbals, lcals) + return # # # def pushOnTodoList(var, expr, glbals, lcals): - global todo - print("Tdo", var) - print(dir(eval(var, glbals, lcals))) - raise NameError("Todo", expr) - todo.append((expr, glbals, lcals)) - return + global todo + print("Tdo", var) + print(dir(eval(var, glbals, lcals))) + raise NameError("Todo", expr) + todo.append((expr, glbals, lcals)) + return - + # -# parseBoolArray(mask): +# parseBoolArray(mask): # def parseBoolArray(mask): - list = [] - for c in mask: - if c == '0': - list.append(False) - else: - list.append(True) - return list + list = [] + for c in mask: + if c == '0': + list.append(False) + else: + list.append(True) + return list -# parseMatrix(args, tokens) +# parseMatrix(args, tokens) # def parseMatrix(args, tokens): - matrix = Matrix( [1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1] ) - i = 0 - for (key, val, sub) in tokens: - if key == 'row': - matrix[i][0] = float(val[0]) - matrix[i][1] = float(val[1]) - matrix[i][2] = float(val[2]) - matrix[i][3] = float(val[3]) - i += 1 - return matrix + matrix = Matrix( [1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1] ) + i = 0 + for (key, val, sub) in tokens: + if key == 'row': + matrix[i][0] = float(val[0]) + matrix[i][1] = float(val[1]) + matrix[i][2] = float(val[2]) + matrix[i][3] = float(val[3]) + i += 1 + return matrix # -# parseDefault(data, tokens, subkeys, exclude): +# parseDefault(data, tokens, subkeys, exclude): # def parseDefault(data, tokens, subkeys, exclude): - for (key, val, sub) in tokens: - if key in subkeys.keys(): - for (key2, val2, sub2) in sub: - defaultKey(key2, val2, sub2, "data.%s" % subkeys[key], [], globals(), locals()) - else: - defaultKey(key, val, sub, "data", exclude, globals(), locals()) + for (key, val, sub) in tokens: + if key in subkeys.keys(): + for (key2, val2, sub2) in sub: + defaultKey(key2, val2, sub2, "data.%s" % subkeys[key], [], globals(), locals()) + else: + defaultKey(key, val, sub, "data", exclude, globals(), locals()) def parseCollection(data, tokens, exclude): - return + return # -# Utilities +# Utilities # # -# extractBpyType(data): +# extractBpyType(data): # def extractBpyType(data): - typeSplit = str(type(data)).split("'") - if typeSplit[0] != '<class ': - return None - classSplit = typeSplit[1].split(".") - if classSplit[0] == 'bpy' and classSplit[1] == 'types': - return classSplit[2] - elif classSplit[0] == 'bpy_types': - return classSplit[1] - else: - return None + typeSplit = str(type(data)).split("'") + if typeSplit[0] != '<class ': + return None + classSplit = typeSplit[1].split(".") + if classSplit[0] == 'bpy' and classSplit[1] == 'types': + return classSplit[2] + elif classSplit[0] == 'bpy_types': + return classSplit[1] + else: + return None # -# Bool(string): +# Bool(string): # def Bool(string): - if string == 'True': - return True - elif string == 'False': - return False - else: - raise NameError("Bool %s?" % string) - + if string == 'True': + return True + elif string == 'False': + return False + else: + raise NameError("Bool %s?" % string) + # -# invalid(condition): +# invalid(condition): # def invalid(condition): - global rigLeg, rigArm, toggle - res = eval(condition, globals()) - try: - res = eval(condition, globals()) - #print("%s = %s" % (condition, res)) - return not res - except: - #print("%s invalid!" % condition) - return True + global rigLeg, rigArm, toggle + res = eval(condition, globals()) + try: + res = eval(condition, globals()) + #print("%s = %s" % (condition, res)) + return not res + except: + #print("%s invalid!" % condition) + return True - + # -# clearScene(context): -# hideLayers(): +# clearScene(context): +# hideLayers(): # - + def clearScene(): - global toggle - scn = bpy.context.scene - for n in range(len(scn.layers)): - scn.layers[n] = True - print("clearScene %s %s" % (toggle & T_Replace, scn)) - if not toggle & T_Replace: - return scn - - for ob in scn.objects: - if ob.type == "MESH" or ob.type == "ARMATURE" or ob.type == 'EMPTY': - scn.objects.active = ob - bpy.ops.object.mode_set(mode='OBJECT') - scn.objects.unlink(ob) - del ob - #print(scn.objects) - return scn + global toggle + scn = bpy.context.scene + for n in range(len(scn.layers)): + scn.layers[n] = True + print("clearScene %s %s" % (toggle & T_Replace, scn)) + if not toggle & T_Replace: + return scn + + for ob in scn.objects: + if ob.type == "MESH" or ob.type == "ARMATURE" or ob.type == 'EMPTY': + scn.objects.active = ob + bpy.ops.object.mode_set(mode='OBJECT') + scn.objects.unlink(ob) + del ob + #print(scn.objects) + return scn def hideLayers(): - scn = bpy.context.scene - for n in range(len(scn.layers)): - if n < 8: - scn.layers[n] = True - else: - scn.layers[n] = False - return + scn = bpy.context.scene + for n in range(len(scn.layers)): + if n < 8: + scn.layers[n] = True + else: + scn.layers[n] = False + return # -# User interface +# User interface # DEBUG= False from bpy.props import * class IMPORT_OT_makehuman_mhx(bpy.types.Operator): - '''Import from MHX file format (.mhx)''' - bl_idname = "import_scene.makehuman_mhx" - bl_description = 'Import from MHX file format (.mhx)' - bl_label = "Import MHX" - bl_space_type = "PROPERTIES" - bl_region_type = "WINDOW" - - filepath = StringProperty(name="File Path", description="File path used for importing the MHX file", maxlen= 1024, default= "") - - scale = FloatProperty(name="Scale", description="Default meter, decimeter = 1.0", default = theScale) - enforce = BoolProperty(name="Enforce version", description="Only accept MHX files of correct version", default=toggle&T_EnforceVersion) - mesh = BoolProperty(name="Mesh", description="Use main mesh", default=toggle&T_Mesh) - proxy = BoolProperty(name="Proxies", description="Use proxies", default=toggle&T_Proxy) - armature = BoolProperty(name="Armature", description="Use armature", default=toggle&T_Armature) - replace = BoolProperty(name="Replace scene", description="Replace scene", default=toggle&T_Replace) - cage = BoolProperty(name="Cage", description="Load mesh deform cage", default=toggle&T_Cage) - clothes = BoolProperty(name="Clothes", description="Include clothes", default=toggle&T_Clothes) - stretch = BoolProperty(name="Stretchy limbs", description="Stretchy limbs", default=toggle&T_Stretch) - face = BoolProperty(name="Face shapes", description="Include facial shapekeys", default=toggle&T_Face) - shape = BoolProperty(name="Body shapes", description="Include body shapekeys", default=toggle&T_Shape) - symm = BoolProperty(name="Symmetric shapes", description="Keep shapekeys symmetric", default=toggle&T_Symm) - diamond = BoolProperty(name="Diamonds", description="Keep joint diamonds", default=toggle&T_Diamond) - bend = BoolProperty(name="Bend joints", description="Bend joints for better IK", default=toggle&T_Bend) - - def execute(self, context): - global toggle - O_EnforceVersion = T_EnforceVersion if self.properties.enforce else 0 - O_Mesh = T_Mesh if self.properties.mesh else 0 - O_Proxy = T_Proxy if self.properties.proxy else 0 - O_Armature = T_Armature if self.properties.armature else 0 - O_Replace = T_Replace if self.properties.replace else 0 - O_Cage = T_Cage if self.properties.cage else 0 - O_Clothes = T_Clothes if self.properties.clothes else 0 - O_Stretch = T_Stretch if self.properties.stretch else 0 - O_Face = T_Face if self.properties.face else 0 - O_Shape = T_Shape if self.properties.shape else 0 - O_Symm = T_Symm if self.properties.symm else 0 - O_Diamond = T_Diamond if self.properties.diamond else 0 - O_Bend = T_Bend if self.properties.bend else 0 - toggle = ( O_EnforceVersion | O_Mesh | O_Proxy | O_Armature | O_Replace | O_Stretch | O_Cage | - O_Face | O_Shape | O_Symm | O_Diamond | O_Bend | O_Clothes | T_MHX ) - - print("Load", self.properties.filepath) - readMhxFile(self.properties.filepath, self.properties.scale) - return {'FINISHED'} - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {'RUNNING_MODAL'} + '''Import from MHX file format (.mhx)''' + bl_idname = "import_scene.makehuman_mhx" + bl_description = 'Import from MHX file format (.mhx)' + bl_label = "Import MHX" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + + filepath = StringProperty(name="File Path", description="File path used for importing the MHX file", maxlen= 1024, default= "") + + scale = FloatProperty(name="Scale", description="Default meter, decimeter = 1.0", default = theScale) + + + + enforce = BoolProperty(name="Enforce version", description="Only accept MHX files of correct version", default=toggle&T_EnforceVersion) + mesh = BoolProperty(name="Mesh", description="Use main mesh", default=toggle&T_Mesh) + proxy = BoolProperty(name="Proxies", description="Use proxies", default=toggle&T_Proxy) + armature = BoolProperty(name="Armature", description="Use armature", default=toggle&T_Armature) + replace = BoolProperty(name="Replace scene", description="Replace scene", default=toggle&T_Replace) + cage = BoolProperty(name="Cage", description="Load mesh deform cage", default=toggle&T_Cage) + clothes = BoolProperty(name="Clothes", description="Include clothes", default=toggle&T_Clothes) + stretch = BoolProperty(name="Stretchy limbs", description="Stretchy limbs", default=toggle&T_Stretch) + face = BoolProperty(name="Face shapes", description="Include facial shapekeys", default=toggle&T_Face) + shape = BoolProperty(name="Body shapes", description="Include body shapekeys", default=toggle&T_Shape) + symm = BoolProperty(name="Symmetric shapes", description="Keep shapekeys symmetric", default=toggle&T_Symm) + diamond = BoolProperty(name="Diamonds", description="Keep joint diamonds", default=toggle&T_Diamond) + bend = BoolProperty(name="Bend joints", description="Bend joints for better IK", default=toggle&T_Bend) + + def execute(self, context): + global toggle + O_EnforceVersion = T_EnforceVersion if self.properties.enforce else 0 + O_Mesh = T_Mesh if self.properties.mesh else 0 + O_Proxy = T_Proxy if self.properties.proxy else 0 + O_Armature = T_Armature if self.properties.armature else 0 + O_Replace = T_Replace if self.properties.replace else 0 + O_Cage = T_Cage if self.properties.cage else 0 + O_Clothes = T_Clothes if self.properties.clothes else 0 + O_Stretch = T_Stretch if self.properties.stretch else 0 + O_Face = T_Face if self.properties.face else 0 + O_Shape = T_Shape if self.properties.shape else 0 + O_Symm = T_Symm if self.properties.symm else 0 + O_Diamond = T_Diamond if self.properties.diamond else 0 + O_Bend = T_Bend if self.properties.bend else 0 + toggle = ( O_EnforceVersion | O_Mesh | O_Proxy | O_Armature | O_Replace | O_Stretch | O_Cage | + O_Face | O_Shape | O_Symm | O_Diamond | O_Bend | O_Clothes | T_MHX ) + + print("Load", self.properties.filepath) + readMhxFile(self.properties.filepath, self.properties.scale) + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} def menu_func(self, context): self.layout.operator(IMPORT_OT_makehuman_mhx.bl_idname, text="MakeHuman (.mhx)...") def register(): - bpy.types.INFO_MT_file_import.append(menu_func) + bpy.types.INFO_MT_file_import.append(menu_func) def unregister(): - bpy.types.INFO_MT_file_import.remove(menu_func) + bpy.types.INFO_MT_file_import.remove(menu_func) if __name__ == "__main__": - try: - unregister() - except: - pass - register() + try: + unregister() + except: + pass + register() # -# Testing +# Testing # """ #readMhxFile("C:/Documents and Settings/xxxxxxxxxxxxxxxxxxxx/Mina dokument/makehuman/exports/foo-25.mhx", 'Classic') -- GitLab