Skip to content
Snippets Groups Projects
io_import_scene_mhx.py 136 KiB
Newer Older
  • Learn to ignore specific revisions
  • Luca Bonavita's avatar
    Luca Bonavita committed
    
        if typ == 'EMPTY':
            ob = bpy.data.objects.new(name, None)
            loadedData['Object'][name] = ob
            linkObject(ob, None)
        else:
            try:
    
                data = loadedData[typ.capitalize()][datName]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            except:
    
                MyError("Failed to find data: %s %s %s" % (name, typ, datName))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                return
    
        try:
            ob = loadedData['Object'][name]
            bpy.context.scene.objects.active = ob
            #print("Found data", ob)
        except:
            ob = None
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            ob = createObject(typ, name, data, datName)
            linkObject(ob, data)
    
        for (key, val, sub) in tokens:
            if key == 'Modifier':
                parseModifier(ob, val, sub)
            elif key == 'Constraint':
    
                parseConstraint(ob.constraints, None, val, sub)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            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'])
    
        if versionInfoStr:
            print('============= updating version string %s' % versionInfoStr)
            ob.MhxVersionStr = versionInfoStr
        else:
            print('============= not updating version str')
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if bpy.context.object == ob:
    
            if ob.type == 'MESH':
                bpy.ops.object.shade_smooth()
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        else:
            print("Context", ob, bpy.context.object, bpy.context.scene.objects.active)
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def createObject(typ, name, data, datName):
    
        # print( "Creating object %s %s %s" % (typ, name, data) )
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        ob = bpy.data.objects.new(name, data)
        if data:
            loadedData[typ.capitalize()][datName] = data
        loadedData['Object'][name] = ob
        return ob
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def linkObject(ob, data):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        #print("Data", data, ob.data)
    
        if data and ob.data is None:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            ob.data = 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):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseModifier(ob, args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def parseModifier(ob, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        name = args[0]
        typ = args[1]
        if typ == 'PARTICLE_SYSTEM':
            return None
        mod = ob.modifiers.new(name, typ)
        for (key, val, sub) in tokens:
    
            if key == 'HookAssignNth':
                if val[0] == 'CURVE':
                    hookAssignNth(mod, int(val[1]), True, ob.data.splines[0].points)
                elif val[0] == 'LATTICE':
                    hookAssignNth(mod, int(val[1]), False, ob.data.points)
                elif val[0] == 'MESH':
                    hookAssignNth(mod, int(val[1]), True, ob.data.vertices)
                else:
    
                    MyError("Unknown hook %s" % val)
    
                defaultKey(key, val, sub, mod)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return mod
    
    def hookAssignNth(mod, n, select, points):
        if select:
            for pt in points:
                pt.select = False
            points[n].select = True
            sel = []
            for pt in points:
                sel.append(pt.select)
            #print(mod, sel, n, points)
    
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.object.hook_reset(modifier=mod.name)
        bpy.ops.object.hook_select(modifier=mod.name)
        bpy.ops.object.hook_assign(modifier=mod.name)
        bpy.ops.object.mode_set(mode='OBJECT')
        return
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseParticleSystem(ob, args, tokens):
    #    parseParticles(particles, args, tokens):
    #    parseParticle(par, args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseParticleSystem(ob, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return psys
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseParticles(psys, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bpy.ops.particle.particle_edit_toggle()
        return particles
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseParticle(par, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        n = 0
        for (key, val, sub) in tokens:
            if key == 'h':
                h = par.hair[n]
    
                h.location = mhxEval(val[0], locals())
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                h.time = int(val[1])
                h.weight = float(val[2])
                n += 1
            elif key == 'location':
    
                par.location = mhxEval(val[0], locals())
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    unpackList(list_of_tuples):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def unpackList(list_of_tuples):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        l = []
        for t in list_of_tuples:
            l.extend(t)
        return l
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseMesh (args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseMesh (args, tokens):
    
        global BMeshAware
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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, [])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        linkObject(ob, me)
    
        if faces:
            try:
                me.polygons
                BMeshAware = True
            except:
                BMeshAware = False
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        mats = []
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        for (key, val, sub) in tokens:
            if key == 'Verts' or key == 'Edges' or key == 'Faces':
                pass
            elif key == 'MeshTextureFaceLayer':
    
                if BMeshAware:
                    parseUvTextureBMesh(val, sub, me)
                else:
                    parseUvTextureNoBMesh(val, sub, me)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                parseVertColorLayer(val, sub, me)
            elif key == 'VertexGroup':
                parseVertexGroup(ob, me, val, sub)
            elif key == 'ShapeKeys':
                parseShapeKeys(ob, me, val, sub)
            elif key == 'Material':
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    mat = loadedData['Material'][val[0]]
                except:
                    mat = None
                if mat:
                    me.materials.append(mat)
            else:
    
                defaultKey(key, val, sub, me)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
        for (key, val, sub) in tokens:
            if key == 'Faces':
    
                if BMeshAware:
                    parseFaces2BMesh(sub, me)
                else:
                    parseFaces2NoBMesh(sub, me)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return me
    
    #
    #    parseVerts(tokens):
    #    parseEdges(tokens):
    #    parseFaces(tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseVerts(tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseEdges(tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        edges = []
        for (key, val, sub) in tokens:
            if key == 'e':
                edges.append((int(val[0]), int(val[1])))
        return edges
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        n = 0
        for (key, val, sub) in tokens:
            if key == 'ft':
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                f.material_index = int(val[0])
                f.use_smooth = int(val[1])
                n += 1
    
            elif key == 'ftn':
                mn = int(val[1])
                us = int(val[2])
                npts = int(val[0])
                for i in range(npts):
    
                    f.material_index = mn
                    f.use_smooth = us
                    n += 1
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            elif key == 'mn':
                fn = int(val[0])
                mn = int(val[1])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                f.material_index = mn
            elif key == 'ftall':
                mat = int(val[0])
                smooth = int(val[1])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    f.material_index = mat
                    f.use_smooth = smooth
        return
    
    
        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 == 'ftn':
                mn = int(val[1])
                us = int(val[2])
                npts = int(val[0])
                for i in range(npts):
                    f = me.faces[n]
                    f.material_index = mn
                    f.use_smooth = us
                    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
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseUvTexData(args, tokens, uvdata):
    
    def parseUvTextureBMesh(args, tokens, me):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        name = args[0]
    
        bpy.ops.mesh.uv_texture_add()
        uvtex = me.uv_textures[-1]
        uvtex.name = name
    
        uvloop = me.uv_layers[-1]
    
        loadedData['MeshTextureFaceLayer'][name] = uvloop
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        for (key, val, sub) in tokens:
            if key == 'Data':
    
                parseUvTexDataBMesh(val, sub, uvloop.data)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            else:
    
                defaultKey(key, val, sub, uvtex)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    def parseUvTexDataBMesh(args, tokens, data):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        n = 0
        for (key, val, sub) in tokens:
            if key == 'vt':
    
                data[n].uv = (float(val[0]), float(val[1]))
                n += 1
                data[n].uv = (float(val[2]), float(val[3]))
                n += 1
                data[n].uv = (float(val[4]), float(val[5]))
                n += 1
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                if len(val) > 6:
    
                    data[n].uv = (float(val[6]), float(val[7]))
                    n += 1
    
        return
    
    def parseUvTextureNoBMesh(args, tokens, me):
        name = args[0]
        uvtex = me.uv_textures.new(name = name)
        loadedData['MeshTextureFaceLayer'][name] = uvtex
        for (key, val, sub) in tokens:
            if key == 'Data':
                parseUvTexDataNoBMesh(val, sub, uvtex.data)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            else:
    
                defaultKey(key, val, sub, uvtex)
    
        return
    
    def parseUvTexDataNoBMesh(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]))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    #
    #    parseVertColorLayer(args, tokens, me):
    #    parseVertColorData(args, tokens, data):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseVertColorLayer(args, tokens, me):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseVertColorData(args, tokens, data):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        n = 0
        for (key, val, sub) in tokens:
            if key == 'cv':
    
                data[n].color1 = mhxEval(val[0])
                data[n].color2 = mhxEval(val[1])
                data[n].color3 = mhxEval(val[2])
                data[n].color4 = mhxEval(val[3])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseVertexGroup(ob, me, args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseVertexGroup(ob, me, args, tokens):
    
        global toggle
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if verbosity > 2:
            print( "Parsing vertgroup %s" % args )
        grpName = args[0]
        try:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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']):
    
            try:
                group = loadedData['VertexGroup'][grpName]
            except KeyError:
                group = ob.vertex_groups.new(grpName)
                loadedData['VertexGroup'][grpName] = group
    
            for (key, val, sub) in tokens:
                if key == 'wv':
                    group.add( [int(val[0])], float(val[1]), 'REPLACE' )
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    
    #
    #    parseShapeKeys(ob, me, args, tokens):
    #    parseShapeKey(ob, me, args, tokens):
    #    addShapeKey(ob, name, vgroup, tokens):
    #    doShape(name):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def doShape(name):
    
        if (toggle & T_Shapekeys) and (name == 'Basis'):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            return True
        else:
            return (toggle & T_Face)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def parseShapeKeys(ob, me, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
            elif key == 'Expression':
                prop = "Mhe" + val[0].capitalize()
    
                parseUnits(prop, ob, sub)
            elif key == 'Viseme':
    
                name = val[0].upper()
                if name in ["REST", "ETC"]:
                    name = name.capitalize()
                prop = "Mhv" + name
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        ob.active_shape_key_index = 0
    
    def parseUnits(prop, ob, sub):
        string = ""
        for words in sub:
            unit = words[0].replace("-","_")
            value = words[1][0]
            string += "%s:%s;" % (unit, value)
        rig = ob.parent
        rig[prop] = string
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseShapeKey(ob, me, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            addShapeKey(ob, name, None, tokens)
        elif lr == 'LR':
            addShapeKey(ob, name+'_L', 'Left', tokens)
            addShapeKey(ob, name+'_R', 'Right', tokens)
        else:
    
            MyError("ShapeKey L/R %s" % lr)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def addShapeKey(ob, name, vgroup, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseArmature (obName, args, tokens)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseArmature (args, tokens):
    
        global toggle, theArmature
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if verbosity > 2:
            print( "Parsing armature %s" % args )
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        amtname = args[0]
        obname = args[1]
        mode = args[2]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        amt = bpy.data.armatures.new(amtname)
    
        ob = createObject('ARMATURE', obname, amt, amtname)
        linkObject(ob, amt)
    
        theArmature = ob
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
        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
    
            elif key == 'RecalcRoll':
    
                for bone in amt.edit_bones:
                    bone.select = False
    
                for name in blist:
                    bone = amt.edit_bones[name]
                    bone.select = True
                bpy.ops.armature.calculate_roll(type='Z')
    
                for bone in amt.edit_bones:
                    rolls[bone.name] = bone.roll
                bpy.ops.object.mode_set(mode='OBJECT')
                for bone in amt.bones:
                    bone['Roll'] = rolls[bone.name]
                bpy.ops.object.mode_set(mode='EDIT')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            else:
    
                defaultKey(key, val, sub, amt, ['MetaRig'])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bpy.ops.object.mode_set(mode='OBJECT')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return amt
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #
    #    parseBone(bone, amt, tokens, heads, tails):
    
    #
    
    def parseBone(bone, amt, tokens, heads, tails):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
            else:
    
                defaultKey(key, val, sub, bone)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return bone
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parsePose (args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parsePose (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        name = args[0]
        ob = loadedData['Object'][name]
        bpy.context.scene.objects.active = ob
        bpy.ops.object.mode_set(mode='POSE')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                pb = pbones[bone]
                pb[prop] = value
            else:
    
                defaultKey(key, val, sub, ob.pose)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bpy.ops.object.mode_set(mode='OBJECT')
        return ob
    
    
    #
    #    parsePoseBone(pbones, args, tokens):
    #    parseArray(data, exts, args):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseBoneGroup(pose, nGrps, args, tokens):
    
        if verbosity > 2:
            print( "Parsing bonegroup %s" % args )
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        name = args[0]
        bpy.ops.pose.group_add()
        bg = pose.bone_groups.active
        loadedData['BoneGroup'][name] = bg
        for (key, val, sub) in tokens:
    
            defaultKey(key, val, sub, bg)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parsePoseBone(pbones, ob, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if invalid(args[1]):
            return
        name = args[0]
        pb = pbones[name]
        amt = ob.data
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
        for (key, val, sub) in tokens:
            if key == 'Constraint':
    
                cns = parseConstraint(pb.constraints, pb, val, sub)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            elif key == 'bpyops':
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                expr = "bpy.ops.%s" % val[0]
    
                raise MhxError("MHX bug: Must not exec %s" % expr)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            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 = mhxEval(val[0])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                #bpy.ops.object.mode_set(mode='POSE')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            else:
    
                defaultKey(key, val, sub, pb)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseArray(data, exts, args):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        n = 1
        for ext in exts:
    
            setattr(data, ext, mhxEval(args[n]))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            n += 1
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    #    parseConstraint(constraints, pb, args, tokens)
    
    def parseConstraint(constraints, pb, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if invalid(args[2]):
            return None
    
        if (toggle&T_Opcns and pb):
            print("Active")
            aob = bpy.context.object
            print("ob", aob)
            aamt = aob.data
            print("amt", aamt)
            apose = aob.pose
            print("pose", apose)
            abone = aamt.bones.active
            print("bone", abone)
            print('Num cns before', len(list(constraints)))
            bpy.ops.pose.constraint_add(type=args[1])
            cns = constraints.active
            print('and after', pb, cns, len(list(constraints)))
        else:
            cns = constraints.new(args[1])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        cns.name = args[0]
        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, ["use_target"])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        #print("cns %s done" % cns.name)
        return cns
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseCurve (args, tokens):
    #    parseSpline(cu, args, tokens):
    #    parseBezier(spline, n, args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseCurve (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    
    def parseTextCurve (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    def parseBezier(bez, args, tokens):
    
        bez.co = mhxEval(args[0])
    
        bez.handle1 = mhxEval(args[1])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bez.handle1_type = args[2]
    
        bez.handle2 = mhxEval(args[3])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bez.handle2_type = args[4]
        return
    
    
    def parsePoint(pt, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        pt.co = theScale*pt.co
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseLattice (args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseLattice (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if verbosity > 2:
            print( "Parsing lattice %s" % args )
        bpy.ops.object.add(type='LATTICE')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        for (key, val, sub) in tokens:
            if key == 'Points':
                parseLatticePoints(val, sub, lat.points)
            else:
    
                defaultKey(key, val, sub, lat)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseLatticePoints(args, tokens, points):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        n = 0
        for (key, val, sub) in tokens:
            if key == 'pt':
    
                v = points[n].co_deform
                v.x = theScale*float(val[0])
                v.y = theScale*float(val[1])
                v.z = theScale*float(val[2])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                n += 1
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseLamp (args, tokens):
    #    parseFalloffCurve(focu, args, tokens):
    
    def parseLamp (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if verbosity > 2:
            print( "Parsing lamp %s" % args )
        bpy.ops.object.add(type='LAMP')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        for (key, val, sub) in tokens:
            if key == 'FalloffCurve':
                parseFalloffCurve(lamp.falloff_curve, val, sub)
            else:
    
                defaultKey(key, val, sub, lamp)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    def parseFalloffCurve(focu, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseGroup (args, tokens):
    #    parseGroupObjects(args, tokens, grp):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    
    def parseGroupObjects(args, tokens, grp):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        for (key, val, sub) in tokens:
            if key == 'ob':
                try:
                    ob = loadedData['Object'][val[0]]
                    grp.objects.link(ob)
                except:
    
                    ob = None
                if ob:
                    print(ob, ob.type, rig, ob.parent)
                    if ob.type == 'ARMATURE':
                        rig = ob
                    elif ob.type == 'EMPTY' and rig and not ob.parent:
                        ob.parent = rig
                        print("SSS")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseWorld (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    #
    #    parseScene (args, tokens):
    #    parseRenderSettings(render, args, tokens):
    #    parseToolSettings(tool, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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",
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    'WeightPaint' : "weight_paint" }
                parseDefault(scn.tool_settings, sub, subkeys, [])
            elif key == 'UnitSettings':
                parseDefault(scn.unit_settings, sub, {}, [])
            else:
    
                defaultKey(key, val, sub, scn)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    
    def parseRenderSettings(render, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
    
    #    parseDefineProperty(args, tokens):
    
    def parseDefineProperty(args, tokens):
    
        prop = "%sProperty" % (args[1])
    
            prop += "%s %s" % (c, option)
    
        prop += ')'
        setattr(bpy.types.Object, args[0], prop)