Skip to content
Snippets Groups Projects
io_import_scene_mhx.py 61.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • Luca Bonavita's avatar
    Luca Bonavita committed
        mod = ob.modifiers.new(name, typ)
        for (key, val, sub) in tokens:
            defaultKey(key, val, sub, 'mod', [], globals(), locals())
        return mod
    
    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', [], globals(), locals())
        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', [], globals(), locals())
        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.is_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
    
    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):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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:
            #x = me.from_pydata(verts, [], faces)
            me.vertices.add(len(verts))
            me.faces.add(len(faces))
            me.vertices.foreach_set("co", unpackList(verts))
            me.faces.foreach_set("vertices_raw", unpackList(faces))
        else:
            #x = me.from_pydata(verts, edges, [])
            me.vertices.add(len(verts))
            me.edges.add(len(edges))
            me.vertices.foreach_set("co", unpackList(verts))
            me.edges.foreach_set("vertices", unpackList(edges))
        #print(x)
        me.update()
        #print(me)
        linkObject(ob, me)
            
        mats = []
        for (key, val, sub) in tokens:
            if key in ('Verts', 'Edges'):
                pass
            elif key == 'Faces':
                parseFaces2(sub, me)
            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:
    
                    me.materials.append(loadedData['Material'][val[0]])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                except:
                    print("Could not add material", val[0])
            else:
                defaultKey(key, val,  sub, "me", [], globals(), locals())
    
        return me
    
    #
    #    parseVerts(tokens):
    #    parseEdges(tokens):
    #    parseFaces(tokens):
    #    parseFaces2(tokens, me):        
    
    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( (float(val[0]), float(val[1]), 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
        
    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]), 0]
                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 == '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):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseUvTexture(args, tokens, me):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        name = args[0]
        uvtex = me.uv_textures.new(name)
        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
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseUvTexData(args, tokens, data):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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):
    
    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", [], globals(), locals())
        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 = eval(val[0])
                data[n].color2 = eval(val[1])
                data[n].color3 = eval(val[2])
                data[n].color4 = eval(val[3])
                n += 1    
        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):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
            group.name = grpName
            loadedData['VertexGroup'][grpName] = group
    
    Campbell Barton's avatar
    Campbell Barton committed
            ob.vertex_groups.assign([int(val[0]) for (key, val, sub) in tokens if key == 'wv'], group, 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):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if (toggle & T_Shape+T_Face) and (name == 'Basis'):
            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
        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, sub)
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    
    def parseShapeKey(ob, me, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def addShapeKey(ob, name, vgroup, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
    
    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] += float(val[1])
                pt[1] += float(val[2])
                pt[2] += float(val[3])
            else:
                defaultKey(key, val,  sub, "skey", [], globals(), locals())
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseArmature (obName, args, tokens)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseArmature (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global toggle,  theScale
        if verbosity > 2:
            print( "Parsing armature %s" % args )
        
        amtname = args[0]
        obname = args[1]
        mode = args[2]
        
        if mode == 'Rigify':
            toggle |= T_Rigify
            theScale = 0.1
            return parseRigify(amtname, obname, tokens)
    
        toggle &= ~T_Rigify
        theScale = 1.0
        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.edit_bones, 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.edit_bones, sub, heads, tails)
            else:
                defaultKey(key, val,  sub, "amt", ['MetaRig'], globals(), locals())
        bpy.ops.object.mode_set(mode='OBJECT')
        return amt
            
    #
    #    parseBone(bone, bones, tokens, heads, tails):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseBone(bone, bones, tokens, heads, tails):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
    
        for (key, val, sub) in tokens:
            if key == "head":
                bone.head = (float(val[0]), float(val[1]), float(val[2]))
            elif key == "tail":
                bone.tail = (float(val[0]), float(val[1]), float(val[2]))
            elif key == "head-as":
                target = val[0]
                if val[1] == 'head':
                    bone.head = heads[bone.name] + bones[target].head - heads[target]
                elif val[1] == 'tail':
                    bone.head = heads[bone.name] + bones[target].tail - tails[target]
                else:
                    raise NameError("head-as %s" % val)
            elif key == "tail-as":
                target = val[0]
                if val[1] == 'head':
                    bone.tail = tails[bone.name] + bones[target].head - heads[target]
                elif val[1] == 'tail':
                    bone.tail = tails[bone.name] + bones[target].tail - tails[target]
                else:
                    raise NameError("tail-as %s" % val)
            elif key == 'hide_select':
                pass
            else:
                defaultKey(key, val,  sub, "bone", [], globals(), locals())
    
        return bone
    
    #
    #    parsePose (args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parsePose (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseBoneGroup(pose, nGrps, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
        return
        print( "Parsing bonegroup %s" % args )
        name = args[0]
        print(dir(pose.bone_groups))
        bg = pose.bone_groups.add()
        print("Created", bg)
        loadedData['BoneGroup'][name] = bg
        for (key, val, sub) in tokens:
            defaultKey(key, val,  sub, "bg", [], globals(), locals())
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parsePoseBone(pbones, ob, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
        #print( "Parsing posebone %s" % args )
        if invalid(args[1]):
            return
        name = args[0]
        pb = pbones[name]
    
        # Make posebone active - don't know how to do this in pose mode
        bpy.ops.object.mode_set(mode='OBJECT')
        ob.data.bones.active = pb.bone
        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':
                expr = "bpy.ops.%s" % val[0]
                print(expr)
                print("ob", bpy.context.active_object)
                print("b", bpy.context.active_bone)
                print("pb", bpy.context.active_pose_bone)
                print("md", bpy.context.mode)
                exec(expr)
                print("show_alive")
            elif key == 'ik_dof':
                parseArray(pb, ["lock_ik_x", "lock_ik_y", "lock_ik_z"], val)
            elif key == 'ik_limit':
                parseArray(pb, ["use_ik_limit_x", "use_ik_limit_y", "use_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)
            else:
                defaultKey(key, val,  sub, "pb", [], globals(), locals())
        #print("pb %s done" % name)
        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:
            expr = "data.%s = %s" % (ext, args[n])
            # print(expr)
            exec(expr)
            n += 1
        return
            
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseConstraint(constraints, args, tokens)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseConstraint(constraints, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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())
        #print("cns %s done" % cns.name)
        return cns
        
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def insertInfluenceIpo(cns, bone):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
        if bone != 'PArmIK_L' and bone != 'PArmIK_R' and bone != 'PLegIK_L' and bone != 'PLegIK_R':
            return False
    
        if (toggle & T_FKIK):
            fcurve = cns.driver_add("influence", 0)
            fcurve.driver.type = 'AVERAGE'
    
            var = fcurve.driver.variables.new()
            var.name = bone
            var.targets[0].id_type = 'OBJECT'
            var.targets[0].id = getObject('HumanRig', 'var.targets[0].id', globals(), locals())
            var.targets[0].bone_target = bone
            var.targets[0].transform_type = 'LOC_X'
            # controller_path = fk_chain.arm_p.path_to_id()
            #var.targets[0].data_path = controller_path + '["use_hinge"]'
    
            mod = fcurve.modifiers[0]
            mod.poly_order = 2
            mod.coefficients[0] = 0.0
            mod.coefficients[1] = 1.0
        elif bone == 'PArmIK_L' or bone == 'PArmIK_R':
            if toggle & T_ArmIK:
                cns.influence = 1.0
            else:
                cns.influence = 0.0
        elif bone == 'PLegIK_L' or bone == 'PLegIK_R':
            if toggle & T_LegIK:
                cns.influence = 1.0
            else:
                cns.influence = 0.0
    
        return True
    
    #
    #    parseCurve (args, tokens):
    #    parseNurb(cu, nNurbs, args, tokens):
    #    parseBezier(nurb, n, args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseCurve (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
        if verbosity > 2:
            print( "Parsing curve %s" % args )
        cu = createObjectAndData(args, 'Curve')
    
        nNurbs = 0
        for (key, val, sub) in tokens:
            if key == 'Nurb':
                parseNurb(cu, nNurbs, val, sub)
                nNurbs += 1
            else:
                defaultKey(key, val, sub, "cu", [], globals(), locals())
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseNurb(cu, nNurbs, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if nNurbs > 0:
            bpy.ops.object.curve_add(type='BEZIER_CURVE')
        print(cu.splines, list(cu.splines), nNurbs)
        nurb = cu.splines[nNurbs]
        nPoints = int(args[0])
        print(nurb, nPoints)
        for n in range(2, nPoints):
            bpy.ops.curve.extrude(mode=1)        
    
        n = 0
        for (key, val, sub) in tokens:
            if key == 'bz':
                parseBezier(nurb, n, val, sub)
                n += 1
            elif key == 'pt':
                parsePoint(nurb, n, val, sub)
                n += 1
            else:
                defaultKey(key, val, sub, "nurb", [], globals(), locals())
        return
        
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def parseBezier(nurb, n, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        bez = nurb[n]
        bez.co = eval(args[0])    
        bez.handle_left = eval(args[1])    
        bez.handle_left_type = args[2]
        bez.handle_right = eval(args[3])    
        bez.handle_right_type = args[4]
        return
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parsePoint(nurb, n, args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        pt = nurb[n]
        pt.co = eval(args[0])
        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
        global todo
        if verbosity > 2:
            print( "Parsing lattice %s" % args )
        lat = createObjectAndData(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
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseLatticePoints(args, tokens, points):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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 = x
                v.y = y
                v.z = z
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                v = points[n].co_deform
                (x,y,z) = eval(val[1])
                v.x = x
                v.y = y
                v.z = z
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                n += 1
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseGroup (args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseGroup (args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def parseGroupObjects(args, tokens, grp):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
        for (key, val, sub) in tokens:
            if key == 'ob':
                try:
                    ob = loadedData['Object'][val[0]]
                    grp.objects.link(ob)
                except:
                    pass
        return
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    postProcess()
    #    setInfluence(bones, cnsName, w):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def postProcess():
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        if not toggle & T_MHX:
            return
        if toggle & T_Rigify:
            return
            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']['Human']
                mod = ob.modifiers[0]
                print(ob, mod, mod.object)
                mod.object = rig
                print("Rig changed", mod.object)
        return            
            
    #
    #    parseProcess(args, tokens):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseProcess(args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        return
        rig = loadedData['Object'][args[0]]
        parents = {}
        objects = []
    
        for (key, val, sub) in tokens:
            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':
                print(val)
                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]
                    print("Done", pb.matrix_local)
                except:
                    pass
            elif key == 'Pose':
                bpy.context.scene.objects.active = rig
                bpy.ops.object.mode_set(mode='POSE')
                pbones = rig.pose.bones    
            elif key == 'Edit':
                bpy.context.scene.objects.active = rig
                bpy.ops.object.mode_set(mode='EDIT')
                ebones = rig.data.edit_bones    
            elif key == 'Object':
                bpy.ops.object.mode_set(mode='OBJECT')
                try:
                    ob = loadedData['Object'][val[0]]
                    objects.append((ob,sub))
                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)
    
        for (ob,tokens) in objects:
            bpy.context.scene.objects.active = ob
            bpy.ops.object.visual_transform_apply()
            #print("vis", list(ob.modifiers))
            bpy.ops.object.modifier_apply(apply_as='DATA', modifier='Armature')
            #print("app", list(ob.modifiers))
    
        bpy.context.scene.objects.active = rig
        bpy.ops.object.mode_set(mode='POSE')
        bpy.ops.pose.armature_apply()
        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')
    
        for (ob,tokens) in objects:
            bpy.context.scene.objects.active = ob
            for (key, val, sub) in tokens:
                if key == 'Modifier':
                    parseModifier(ob, val, sub)
    
        return            
    
    #
    #    defaultKey(ext, args, tokens, var, exclude, glbals, lcals):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def defaultKey(ext, args, tokens, var, exclude, glbals, lcals):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        global todo
    
        if ext == 'Property':
            expr = "%s['%s'] = %s" % (var, args[0], args[1])
            print("Property", expr)
            exec(expr, glbals, lcals)
            #print("execd")
            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:
            #print("Failed ",expr)
            todo.append((expr, glbals, lcals))
        return
                
    #
    #    parseBoolArray(mask):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseBoolArray(mask):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        list = []
        for c in mask:
            if c == '0':            
                list.append(False)
            else:
                list.append(True)
        return list
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    #    parseMatrix(args, tokens)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    def parseMatrix(args, tokens):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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