All pastes #707705 Raw Edit

Mine

public text v1 · immutable
#707705 ·published 2007-09-23 05:46 UTC
rendered paste body
from Blender import *
from Blender.Mathutils import *
from test_fbx import test_fbx

fbx_test = test_fbx

do_debug = 0

class FBXMultipleKeyBag (list):
	pass

#FBX dicts are kindof like normal dicts,
#only they support more then one bucket using a key.
class FBXDict (object):
	_list = 0 #list for preserving order
	_dict = 0 #dict for fast access
	name = 0
	value = 0
	
	def __init__(self, name):
		self._list = []
		self._dict = {}
		self.name = name
		self.value = 0
		
	def __getitem__(self, item, includeall=0):
		"""
		includeall means if there are multiple keys
		of the same name, a list of their values are returned
		"""
		
		global do_debug
		
		if self._dict.has_key(item)==0:
			raise KeyError("item no in dict")
		
		if do_debug == 0 or includeall == 1:
			if type(self._dict[item]) == type(FBXMultipleKeyBag):
				return self._dict[item][0]
			else: return self._dict[item]
		else: return self._dict[item]
	
	
	def __iter__(self):
		return self._list.__iter__()
	
	#convert integer number of tabs to whitespace
	def tlevel(self, level):
		s = ""
		for x in xrange(level): s += "  "
		return s
	
	def __repr__(self, tlevel=0):
		#return self._dict.__repr__()
	
		s = ""
		tab = self.tlevel(tlevel)
		
		for l in self._list:
			if type(l[1]) == FBXDict:
				s += "\n" + tab + l[0] + ": "
				
				if type(l[1].value) == list:
					i = 0
					for v in l[1].value:
						if type(v) == str:
							s += "\"" + str(v) + "\""
						else: s += repr(v)
						if i != len(l[1].value)-1:
							s += ", "
						i += 1
					s += " "
				elif type(l[1].value) == str and len(l[1].value) > 0:
					s += "\"" + l[1].value + "\" "
						
				s += "{\n"
				s += l[1].__repr__(tlevel + 1)
				s += tab +"}\n"
			elif type(l[1]) == list:
				i = 0
				s += tab + l[0] + ": "
				for item in l[1]:
					if type(item) == str:
						s += "\"" + str(item) + "\""
					else: s += repr(item)
					if i != len(l[1])-1:
						s += ", "
					i += 1
				s += "\n"
			#have special case for strings, to output "string" instead of 'string'
			elif type(l[1]) == str:
				s += tab + l[0] + ": \"" + str(l[1]) + "\"\n"	
			else:
				s += tab + l[0] + ": " + repr(l[1]) + "\n"
		
		return s
	
	def __str__(self):
		return self.__repr__()
			
	def getitem(self, item, includeall=0):
		return self.__getitem__(item, includeall)
	
	def __setitem__(self, item, val):
		self._list.append([item, val])
		
		#check for if this key name already exists, and if
		#so keep track of the different values by putting them
		#in a FBXMultipleKeyBag, which is just a straight
		#copy (subclass) of list.
		if self._dict.has_key(item) == 0:
			self._dict[item] = val
		else:
			if type(self._dict[item]) != type(FBXMultipleKeyBag):
				self._dict[item] = FBXMultipleKeyBag([self._dict[item], val])
			else:
				self._dict[item].append(val)
	
def PreprocessFBX(st):
	def stripwhite(l):
		l = l.replace("\t", "").replace(" ", "").replace("\n", "").replace("\r", "")
		return l
	
	lines = [""]
	
	in_comment = 0
	for s in st:
		if s == "\n":
			lines.append("")
			in_comment = 0
			continue
		
		if s == ";": in_comment = 1
		
		if s == "\r": continue #don't include \r's 
		if in_comment==0: lines[-1] += s
	
	lines2 = []
	for l in lines:
		if len(stripwhite(l)) > 0:
			lines2.append(l)
	lines = lines2
		
	# remove comments and \n
	#lines = [l[:-1].rstrip() for l in lines if not l.lstrip().startswith(';')]

	# remove whitespace
	#lines = [l for l in lines if l]
	
	#this part of the code written by campbell barton, aka ideasman_42
	# remove multiline float lists
	def unmultiline(i):
		lines[i-1] = lines[i-1] + lines.pop(i).lstrip()

	
	# Multiline floats, used for verts and matricies, this is harderto read so detect and make into 1 line.
	i = 0
	lastl = 0
	while i < len(lines):
		l = lines[i].strip()
		if l.startswith(',') or (lastl!=0 and lastl.endswith(",")):
			unmultiline(i)
			i-=1
		try:
			float(l.split(',', 1)[0])
			unmultiline(i)
			i-=1
		except:
			pass
			
		lastl = l
		i += 1
	
	return lines

"""
   # remove comments and \n
	lines = [l[:-1].rstrip() for l in lines if not l.lstrip().startswith(';')]

	# remove whitespace
	lines = [l for l in lines if l]
"""

def isnumeral(st):
	if len(st) == 0: return 0
	
	d = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-']
	for s in st:
		if s not in d: return 0
	return 1

def ParseValue(val):
	
	#break val into blocks
	blocks = [""]
	in_str = 0
	for s in val:
		if s == "\"": #\"
			if in_str == 0: in_str = 1
			else: in_str = 0
			continue
		
		if in_str==0 and (s == "\t" or s == "\n" or s == "\r" or s == " "):
			continue
		
		if s == "," and in_str==0:
			blocks.append("")
			continue
		
		blocks[-1] += s
	
	for i in xrange(len(blocks)):
		b = blocks[i]
		
		#ok, parse the value
		if isnumeral(b):
			if "." in b: #it's a float
				b = float(b)
			else: #it's an int
				b = int(b)
			blocks[i] = b
	
	if len(blocks) == 1: return blocks[0]
	else: return blocks	
			
def ParseFBX(string1, name="root"):
	lines = PreprocessFBX(string1)
	
	
	fdict = FBXDict(name)
	
	li = 0
	while li < len(lines):
		i = 0

		#read key name, and value if it has one, or recurse
		#if its nested subdict.
		key = ""
		val = ""
		state = 'r' #can be 'r' for reading key, 'v' for reading val.
		l = lines[li]
		in_str = 0
		startsblock = 0
		while i < len(l):
			#break on closing brackets
			if l[i] == "}":
				break
			
			if l[i] == "{" and in_str == 0:
				startsblock = 1
				break
			
			if l[i] == ":" and state == 'r':
				state = 'v'
				i += 1
				continue
			
			if (l[i] == "\t" or l[i] == " ") and (state == 'r' or in_str == 0):
				i += 1
				continue
				
			if l[i] == "\n" or l[i] == "\r":
				i += 1
				continue
			
			if l[i] == "\"" and state == 'v': #\"
				if in_str == 1: in_str = 0
				else: in_str = 1
				
				val += "\"" #\" this comment fixes syntax highlighting in blender
				i += 1
				continue
			
			if state == 'r':
				key += l[i]
			else:
				val += l[i] 
			
			i += 1

		#key can be a null string if
		#we just processed a } closing bracket
		#line
		if key == "":
			li += 1
			continue
		
		if startsblock:
			#make subset of lines
			lines2 = []
			
			in_str = 0
			level = 1
			for l2 in lines[li+1:]:
				if level > 0:
					lines2.append(l2)
				else:
					break

				for s in l2:
					if s == "\"": #\"
						if in_str==0: in_str = 1
						else: in_str = 0
					
					if in_str == 0:
						if s == "{": level += 1
						elif s == "}": level -= 1
			

			#print lines2
			#remove subset from lines
			lines = lines[:li] + lines[li+len(lines2):]
				
			#recurse to get nested subdict.
			#hackishly, we combine the subset lines (lines2)
			#back into one big string.
			s = ""
			for l in lines2: s += l + "\n"
			fdict2 = ParseFBX(s, key)
			fdict2.value = ParseValue(val)
			fdict[key] = fdict2
		else:
			val = ParseValue(val)
			
			fdict[key] = val
					
		li += 1

	return fdict

print "\nparsing. . ."
result = ParseFBX(fbx_test)

"""
a = repr(result)
s2 = ""
i = 0
limit = 40500
for s in a:
	if i > limit: break
	s2 += s
	i += 1
print s2
"""

def import_object(fdict):
	pass

def import_mesh(fdict):
	verts = fdict['Vertices']

def import_objects(fdict):
	for key, val in fdict:
		if key == "Model":
			name = val.value[0]
			type = val.value[1]
			
			if type == "Mesh":
				print "found a mesh!"
				import_mesh(fdict)
				
for key, val in result:
	if key == "Objects":
		import_objects(val)