Skip to content
Snippets Groups Projects
io_import_scene_mhx.py 52.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • Brendon Murphy's avatar
    Brendon Murphy committed
    
    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
    
    #
    #	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
    
    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
    
    def parseParticle(par, args, tokens):
    	n = 0
    	for (key, val, sub) in tokens:
    		if key == 'h':
    
    			h = par.is_hair[n]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    			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):
    #
    
    def unpackList(list_of_tuples):
    	l = []
    	for t in list_of_tuples:
    		l.extend(t)
    	return l
    
    #
    #	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:
    		#x = me.from_pydata(verts, [], faces)
    		me.add_geometry(len(verts), 0, len(faces))
    
    		me.vertices.foreach_set("co", unpackList(verts))
    		me.faces.foreach_set("vertices_raw", unpackList(faces))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    	else:
    		#x = me.from_pydata(verts, edges, [])
    		me.add_geometry(len(verts), len(edges), 0)
    
    		me.vertices.foreach_set("co", unpackList(verts))
    		me.edges.foreach_set("vertices", unpackList(edges))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    	#print(x)
    	me.update()
    	#print(me)
    	linkObject(ob, me)
    		
    	mats = []
    	for (key, val, sub) in tokens:
    		if key == 'Verts' or \
    		   key == '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.add_material(loadedData['Material'][val[0]])
    			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):		
    #
    
    def parseVerts(tokens):
    	verts = []
    	for (key, val, sub) in tokens:
    		if key == 'v':
    			verts.append( (float(val[0]), float(val[1]), 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]), 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])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    			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
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    	return
    
    
    #
    #	parseUvTexture(args, tokens, me):
    #	parseUvTexData(args, tokens, uvdata):
    #
    
    def parseUvTexture(args, tokens, me):
    	me.add_uv_texture()
    	uvtex = me.uv_textures[-1]
    	name = args[0]
    	uvtex.name = 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
    
    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):
    #
    
    def parseVertColorLayer(args, tokens, me):
    	name = args[0]
    	print("VertColorLayer", name)
    	me.add_vertex_color()
    	vcol = me.vertex_colors[-1]
    	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
    
    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
    
    
    #
    #	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.add_vertex_group(grpName)
    		group.name = grpName
    		loadedData['VertexGroup'][grpName] = group
    		for (key, val, sub) in tokens:
    			if key == 'wv':
    				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):
    #
    
    def doShape(name):
    	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, sub)
    	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
    
    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
    
    	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())
    
    	return	
    
    	
    #
    #	parseArmature (obName, args, tokens)
    #
    
    def parseArmature (args, tokens):
    	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):
    #
    
    def parseBone(bone, bones, tokens, heads, tails):
    	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':
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    			pass
    		else:
    			defaultKey(key, val,  sub, "bone", [], globals(), locals())
    
    	return bone
    
    #
    #	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):
    #
    
    def parseBoneGroup(pose, nGrps, args, tokens):
    	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
    
    def parsePoseBone(pbones, ob, args, tokens):
    	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)
    
    Campbell Barton's avatar
    Campbell Barton committed
    			print("show_alive")
    
    Brendon Murphy's avatar
    Brendon Murphy 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)
    		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
    		
    #
    #	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]
    
    	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, ["pos_lock_x", "pos_lock_y", "pos_lock_z"], val)
    		elif key == 'rot_lock':
    			parseArray(cns, ["rot_lock_x", "rot_lock_y", "rot_lock_z"], val)
    		else:
    			defaultKey(key, val,  sub, "cns", [], globals(), locals())
    	#print("cns %s done" % cns.name)
    	return cns
    	
    def insertInfluenceIpo(cns, bone):
    	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"]'
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    		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):
    #
    
    def parseCurve (args, tokens):
    	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
    
    def parseNurb(cu, nNurbs, args, tokens):
    	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
    	
    def parseBezier(nurb, n, args, tokens):
    	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]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    	return
    
    def parsePoint(nurb, n, args, tokens):
    	pt = nurb[n]
    	pt.co = eval(args[0])
    	return
    
    #
    #	parseLattice (args, tokens):
    #
    
    def parseLattice (args, tokens):
    	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
    
    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 = x
    			v.y = y
    			v.z = z
    
    
    			v = points[n].co_deform
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    			(x,y,z) = eval(val[1])
    			v.x = x
    			v.y = y
    			v.z = z
    
    			n += 1
    	return
    
    #
    #	parseGroup (args, tokens):
    #
    
    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
    
    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
    
    #
    #	postProcess()
    #	setInfluence(bones, cnsName, w):
    #
    
    def postProcess():
    	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):
    #
    
    def parseProcess(args, tokens):
    	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)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    			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:
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    			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):
    #
    
    def defaultKey(ext, args, tokens, var, exclude, glbals, lcals):
    	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):
    #
    
    def parseBoolArray(mask):
    	list = []
    	for c in mask:
    		if c == '0':			
    			list.append(False)
    		else:
    			list.append(True)
    	return list
    
    #	parseMatrix(args, tokens)
    #