Пример #1
0
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
    '''
	Mainly uses comprehensiveImageLoad
	but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
	'''

    if '_' in imagepath:
        image = BPyImage.comprehensiveImageLoad(imagepath,
                                                DIR,
                                                PLACE_HOLDER=False,
                                                RECURSIVE=IMAGE_SEARCH)
        if image: return image
        # Did the exporter rename the image?
        image = BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '),
                                                DIR,
                                                PLACE_HOLDER=False,
                                                RECURSIVE=IMAGE_SEARCH)
        if image: return image

    # Return an image, placeholder if it dosnt exist
    image = BPyImage.comprehensiveImageLoad(imagepath,
                                            DIR,
                                            PLACE_HOLDER=True,
                                            RECURSIVE=IMAGE_SEARCH)
    return image
Пример #2
0
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
	'''
	Mainly uses comprehensiveImageLoad
	but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
	'''
	
	if '_' in imagepath:
		image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
		if image: return image
		# Did the exporter rename the image?
		image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
		if image: return image
	
	# Return an image, placeholder if it dosnt exist
	image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
	return image
Пример #3
0
def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
	#print previous_chunk.bytes_read, 'BYTES READ'
	contextObName= None
	contextLamp= [None, None] # object, Data
	contextMaterial= None
	contextMatrix_rot= None # Blender.Mathutils.Matrix(); contextMatrix.identity()
	#contextMatrix_tx= None # Blender.Mathutils.Matrix(); contextMatrix.identity()
	contextMesh_vertls= None
	contextMesh_facels= None
	contextMeshMaterials= {} # matname:[face_idxs]
	contextMeshUV= None
	
	TEXTURE_DICT={}
	MATDICT={}
	TEXMODE= Mesh.FaceModes['TEX']
	
	# Localspace variable names, faster.
	STRUCT_SIZE_1CHAR= calcsize('c')
	STRUCT_SIZE_2FLOAT= calcsize('2f')
	STRUCT_SIZE_3FLOAT= calcsize('3f')
	STRUCT_SIZE_UNSIGNED_SHORT= calcsize('H')
	STRUCT_SIZE_4UNSIGNED_SHORT= calcsize('4H')
	STRUCT_SIZE_4x3MAT= calcsize('ffffffffffff')
	_STRUCT_SIZE_4x3MAT= calcsize('fffffffffffff')
	# STRUCT_SIZE_4x3MAT= calcsize('ffffffffffff')
	# print STRUCT_SIZE_4x3MAT, ' STRUCT_SIZE_4x3MAT'
	
	def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
		
		materialFaces= set() # faces that have a material. Can optimize?
		
		# Now make copies with assigned materils.
		
		def makeMeshMaterialCopy(matName, faces):			
			'''
			Make a new mesh with only face the faces that use this material.
			faces can be any iterable object - containing ints.
			'''
			
			faceVertUsers = [False] * len(myContextMesh_vertls)
			ok=0
			for fIdx in faces:
				for vindex in myContextMesh_facels[fIdx]:
					faceVertUsers[vindex] = True
					if matName != None: # if matName is none then this is a set(), meaning we are using the untextured faces and do not need to store textured faces.
						materialFaces.add(fIdx)
					ok=1
			
			if not ok:
				return
					
			myVertMapping = {}
			vertMappingIndex = 0
			
			vertsToUse = [i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i]]
			myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
			
			tempName= '%s_%s' % (contextObName, matName) # matName may be None.
			bmesh = bpy.data.meshes.new(tempName)
			
			if matName == None:
				img= None
			else:
				bmat = MATDICT[matName][1]
				bmesh.materials= [bmat]
				try:	img= TEXTURE_DICT[bmat.name]
				except:	img= None
				
			bmesh_verts = bmesh.verts
			bmesh_verts.extend( [Vector()] )
			bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
			# +1 because of DUMMYVERT
			face_mapping= bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
			
			if bmesh.faces and (contextMeshUV or img):
				bmesh.faceUV= 1
				for ii, i in enumerate(faces):
					
					# Mapped index- faces may have not been added- if so, then map to the correct index
					# BUGGY API - face_mapping is not always the right length
					map_index= face_mapping[ii]
					
					if map_index != None:
						targetFace= bmesh.faces[map_index]
						if contextMeshUV:
							# v.index-1 because of the DUMMYVERT
							targetFace.uv= [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
						if img:
							targetFace.image= img
			
			# bmesh.transform(contextMatrix)
			ob = SCN_OBJECTS.new(bmesh, tempName)
			'''
			if contextMatrix_tx:
				ob.setMatrix(contextMatrix_tx)
			'''
			
			if contextMatrix_rot:
				ob.setMatrix(contextMatrix_rot)
			
			importedObjects.append(ob)
			bmesh.calcNormals()
		
		for matName, faces in myContextMeshMaterials.iteritems():
			makeMeshMaterialCopy(matName, faces)
			
		if len(materialFaces)!=len(myContextMesh_facels):
			# Invert material faces.
			makeMeshMaterialCopy(None, set(range(len( myContextMesh_facels ))) - materialFaces)
			#raise 'Some UnMaterialed faces', len(contextMesh.faces)
	
	#a spare chunk
	new_chunk= chunk()
	temp_chunk= chunk()
	
	CreateBlenderObject = False

	#loop through all the data for this chunk (previous chunk) and see what it is
	while (previous_chunk.bytes_read<previous_chunk.length):
		#print '\t', previous_chunk.bytes_read, 'keep going'
		#read the next chunk
		#print 'reading a chunk'
		read_chunk(file, new_chunk)

		#is it a Version chunk?
		if (new_chunk.ID==VERSION):
			#print 'if (new_chunk.ID==VERSION):'
			#print 'found a VERSION chunk'
			#read in the version of the file
			#it's an unsigned short (H)
			temp_data= file.read(calcsize('I'))
			version = unpack('<I', temp_data)[0]
			new_chunk.bytes_read+= 4 #read the 4 bytes for the version number
			#this loader works with version 3 and below, but may not with 4 and above
			if (version>3):
				print '\tNon-Fatal Error:  Version greater than 3, may not load correctly: ', version

		#is it an object info chunk?
		elif (new_chunk.ID==OBJECTINFO):
			#print 'elif (new_chunk.ID==OBJECTINFO):'
			# print 'found an OBJECTINFO chunk'
			process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH)
			
			#keep track of how much we read in the main chunk
			new_chunk.bytes_read+=temp_chunk.bytes_read

		#is it an object chunk?
		elif (new_chunk.ID==OBJECT):
			
			if CreateBlenderObject:
				putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
				contextMesh_vertls= []; contextMesh_facels= []
			
				## preparando para receber o proximo objeto
				contextMeshMaterials= {} # matname:[face_idxs]
				contextMeshUV= None
				#contextMesh.vertexUV= 1 # Make sticky coords.
				# Reset matrix
				contextMatrix_rot= None
				#contextMatrix_tx= None
				
			CreateBlenderObject= True
			tempName= read_string(file)
			contextObName= tempName
			new_chunk.bytes_read += len(tempName)+1
		
		#is it a material chunk?
		elif (new_chunk.ID==MATERIAL):
			#print 'elif (new_chunk.ID==MATERIAL):'
			contextMaterial= bpy.data.materials.new('Material')
		
		elif (new_chunk.ID==MAT_NAME):
			#print 'elif (new_chunk.ID==MAT_NAME):'
			material_name= read_string(file)
			
			#plus one for the null character that ended the string
			new_chunk.bytes_read+= len(material_name)+1
			
			contextMaterial.name= material_name.rstrip() # remove trailing  whitespace
			MATDICT[material_name]= (contextMaterial.name, contextMaterial)
		
		elif (new_chunk.ID==MAT_AMBIENT):
			#print 'elif (new_chunk.ID==MAT_AMBIENT):'
			read_chunk(file, temp_chunk)
			if (temp_chunk.ID==MAT_FLOAT_COLOR):
				temp_data=file.read(calcsize('3f'))
				temp_chunk.bytes_read+=12
				contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)]
			elif (temp_chunk.ID==MAT_24BIT_COLOR):
				temp_data=file.read(calcsize('3B'))
				temp_chunk.bytes_read+= 3
				contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
			else:
				skip_to_end(file, temp_chunk)
			new_chunk.bytes_read+= temp_chunk.bytes_read

		elif (new_chunk.ID==MAT_DIFFUSE):
			#print 'elif (new_chunk.ID==MAT_DIFFUSE):'
			read_chunk(file, temp_chunk)
			if (temp_chunk.ID==MAT_FLOAT_COLOR):
				temp_data=file.read(calcsize('3f'))
				temp_chunk.bytes_read+=12
				contextMaterial.rgbCol=[float(col) for col in unpack('<3f', temp_data)]
			elif (temp_chunk.ID==MAT_24BIT_COLOR):
				temp_data=file.read(calcsize('3B'))
				temp_chunk.bytes_read+= 3
				contextMaterial.rgbCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
			else:
				skip_to_end(file, temp_chunk)
			new_chunk.bytes_read+= temp_chunk.bytes_read

		elif (new_chunk.ID==MAT_SPECULAR):
			#print 'elif (new_chunk.ID==MAT_SPECULAR):'
			read_chunk(file, temp_chunk)
			if (temp_chunk.ID==MAT_FLOAT_COLOR):
				temp_data=file.read(calcsize('3f'))
				temp_chunk.bytes_read+=12
				contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)]
			elif (temp_chunk.ID==MAT_24BIT_COLOR):
				temp_data=file.read(calcsize('3B'))
				temp_chunk.bytes_read+= 3
				contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
			else:
				skip_to_end(file, temp_chunk)
			new_chunk.bytes_read+= temp_chunk.bytes_read
			
		elif (new_chunk.ID==MAT_TEXTURE_MAP):
			#print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):'
			new_texture= bpy.data.textures.new('Diffuse')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				#print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name=read_string(file)
					#img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
					
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+= temp_chunk.bytes_read
			
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'DIFFUSE')
			
		elif (new_chunk.ID==MAT_SPECULAR_MAP):
			#print 'elif (new_chunk.ID==MAT_SPECULAR_MAP):'
			new_texture= bpy.data.textures.new('Specular')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name= read_string(file)
					#img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read+= (len(texture_name)+1) #plus one for the null character that gets removed
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+= temp_chunk.bytes_read
				
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'SPECULAR')
	
		elif (new_chunk.ID==MAT_OPACITY_MAP):
			#print 'new_texture=Blender.Texture.New('Opacity')'
			new_texture= bpy.data.textures.new('Opacity')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name= read_string(file)
					#img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+= temp_chunk.bytes_read
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'OPACITY')

		elif (new_chunk.ID==MAT_BUMP_MAP):
			#print 'elif (new_chunk.ID==MAT_BUMP_MAP):'
			new_texture= bpy.data.textures.new('Bump')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name= read_string(file)
					#img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+=temp_chunk.bytes_read
				
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'BUMP')
			
		elif (new_chunk.ID==MAT_TRANSPARENCY):
			#print 'elif (new_chunk.ID==MAT_TRANSPARENCY):'
			read_chunk(file, temp_chunk)
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			
			temp_chunk.bytes_read+=2
			contextMaterial.alpha= 1-(float(unpack('<H', temp_data)[0])/100)
			new_chunk.bytes_read+=temp_chunk.bytes_read


		elif (new_chunk.ID==OBJECT_LAMP): # Basic lamp support.
			
			temp_data=file.read(STRUCT_SIZE_3FLOAT)
			
			x,y,z=unpack('<3f', temp_data)
			new_chunk.bytes_read+=STRUCT_SIZE_3FLOAT
			
			contextLamp[1]= bpy.data.lamps.new()
			contextLamp[0]= SCN_OBJECTS.new(contextLamp[1])
			importedObjects.append(contextLamp[0])
			
			#print 'number of faces: ', num_faces
			#print x,y,z
			contextLamp[0].setLocation(x,y,z)
			
			# Reset matrix
			contextMatrix_rot= None
			#contextMatrix_tx= None
			#print contextLamp.name, 
			
		elif (new_chunk.ID==OBJECT_MESH):
			# print 'Found an OBJECT_MESH chunk'
			pass
		elif (new_chunk.ID==OBJECT_VERTICES):
			'''
			Worldspace vertex locations
			'''
			# print 'elif (new_chunk.ID==OBJECT_VERTICES):'
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_verts=unpack('<H', temp_data)[0]
			new_chunk.bytes_read+=2
			
			# print 'number of verts: ', num_verts
			def getvert():
				temp_data= unpack('<3f', file.read(STRUCT_SIZE_3FLOAT))
				new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each
				return temp_data
			
			#contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed.
			contextMesh_vertls= [getvert() for i in xrange(num_verts)]
			
			#print 'object verts: bytes read: ', new_chunk.bytes_read

		elif (new_chunk.ID==OBJECT_FACES):
			# print 'elif (new_chunk.ID==OBJECT_FACES):'
			temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_faces= unpack('<H', temp_data)[0]
			new_chunk.bytes_read+= 2
			#print 'number of faces: ', num_faces
			
			def getface():
				# print '\ngetting a face'
				temp_data= file.read(STRUCT_SIZE_4UNSIGNED_SHORT)
				new_chunk.bytes_read+= STRUCT_SIZE_4UNSIGNED_SHORT #4 short ints x 2 bytes each
				v1,v2,v3,dummy= unpack('<4H', temp_data)
				return v1, v2, v3
			
			contextMesh_facels= [ getface() for i in xrange(num_faces) ]


		elif (new_chunk.ID==OBJECT_MATERIAL):
			# print 'elif (new_chunk.ID==OBJECT_MATERIAL):'
			material_name= read_string(file)
			new_chunk.bytes_read += len(material_name)+1 # remove 1 null character.
			
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_faces_using_mat = unpack('<H', temp_data)[0]
			new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
			
			def getmat():
				temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
				new_chunk.bytes_read+= STRUCT_SIZE_UNSIGNED_SHORT
				return unpack('<H', temp_data)[0]
			
			contextMeshMaterials[material_name]= [ getmat() for i in xrange(num_faces_using_mat) ]
			
			#look up the material in all the materials

		elif (new_chunk.ID==OBJECT_UV):
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_uv=unpack('<H', temp_data)[0]
			new_chunk.bytes_read+= 2
			
			def getuv():
				temp_data=file.read(STRUCT_SIZE_2FLOAT)
				new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each
				return Vector( unpack('<2f', temp_data) )
				
			contextMeshUV= [ getuv() for i in xrange(num_uv) ]
		
		elif (new_chunk.ID== OBJECT_TRANS_MATRIX):
			# How do we know the matrix size? 54 == 4x4 48 == 4x3
			temp_data=file.read(STRUCT_SIZE_4x3MAT)
			data= list( unpack('<ffffffffffff', temp_data)  )
			new_chunk.bytes_read += STRUCT_SIZE_4x3MAT
			
			contextMatrix_rot= Blender.Mathutils.Matrix(\
			 data[:3] + [0],\
			 data[3:6] + [0],\
			 data[6:9] + [0],\
			 data[9:] + [1])
			
			
			'''
			contextMatrix_rot= Blender.Mathutils.Matrix(\
			 data[:3] + [0],\
			 data[3:6] + [0],\
			 data[6:9] + [0],\
			 [0,0,0,1])
			'''
			
			'''
			contextMatrix_rot= Blender.Mathutils.Matrix(\
			 data[:3] ,\
			 data[3:6],\
			 data[6:9])
			'''
			
			'''
			contextMatrix_rot = Blender.Mathutils.Matrix()
			m = 0
			for j in xrange(4):
				for i in xrange(3):
					contextMatrix_rot[j][i] = data[m]
					m+=1
			
			contextMatrix_rot[0][3]=0;
			contextMatrix_rot[1][3]=0;
			contextMatrix_rot[2][3]=0;
			contextMatrix_rot[3][3]=1;
			'''
			
			#contextMatrix_rot.resize4x4()
			#print "MTX"
			#print contextMatrix_rot
			contextMatrix_rot.invert()
			#print contextMatrix_rot
			#contextMatrix_tx = Blender.Mathutils.TranslationMatrix(0.5 * Blender.Mathutils.Vector(data[9:]))
			#contextMatrix_tx.invert()
			
			#tx.invert()
			
			#contextMatrix = contextMatrix * tx
			#contextMatrix = contextMatrix  *tx
			
		elif  (new_chunk.ID==MAT_MAP_FILENAME):
			texture_name=read_string(file)
			try:
				TEXTURE_DICT[contextMaterial.name]
			except:
				#img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
				img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
			
			new_chunk.bytes_read+= len(texture_name)+1 #plus one for the null character that gets removed
		
		else: #(new_chunk.ID!=VERSION or new_chunk.ID!=OBJECTINFO or new_chunk.ID!=OBJECT or new_chunk.ID!=MATERIAL):
			# print 'skipping to end of this chunk'
			buffer_size=new_chunk.length-new_chunk.bytes_read
			binary_format='%ic' % buffer_size
			temp_data=file.read(calcsize(binary_format))
			new_chunk.bytes_read+=buffer_size


		#update the previous chunk bytes read
		# print 'previous_chunk.bytes_read += new_chunk.bytes_read'
		# print previous_chunk.bytes_read, new_chunk.bytes_read
		previous_chunk.bytes_read += new_chunk.bytes_read
		## print 'Bytes left in this chunk: ', previous_chunk.length-previous_chunk.bytes_read
	
	# FINISHED LOOP
	# There will be a number of objects still not added
	if contextMesh_facels != None:
		putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
Пример #4
0
def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
	#print previous_chunk.bytes_read, 'BYTES READ'
	contextObName= None
	contextLamp= [None, None] # object, Data
	contextMaterial= None
	contextMatrix_rot= None # Blender.Mathutils.Matrix(); contextMatrix.identity()
	#contextMatrix_tx= None # Blender.Mathutils.Matrix(); contextMatrix.identity()
	contextMesh_vertls= None
	contextMesh_facels= None
	contextMeshMaterials= {} # matname:[face_idxs]
	contextMeshUV= None
	
	TEXTURE_DICT={}
	MATDICT={}
	TEXMODE= Mesh.FaceModes['TEX']
	
	# Localspace variable names, faster.
	STRUCT_SIZE_1CHAR= calcsize('c')
	STRUCT_SIZE_2FLOAT= calcsize('2f')
	STRUCT_SIZE_3FLOAT= calcsize('3f')
	STRUCT_SIZE_UNSIGNED_SHORT= calcsize('H')
	STRUCT_SIZE_4UNSIGNED_SHORT= calcsize('4H')
	STRUCT_SIZE_4x3MAT= calcsize('ffffffffffff')
	_STRUCT_SIZE_4x3MAT= calcsize('fffffffffffff')
	# STRUCT_SIZE_4x3MAT= calcsize('ffffffffffff')
	# print STRUCT_SIZE_4x3MAT, ' STRUCT_SIZE_4x3MAT'
	
	def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
		
		materialFaces= set() # faces that have a material. Can optimize?
		
		# Now make copies with assigned materils.
		
		def makeMeshMaterialCopy(matName, faces):			
			'''
			Make a new mesh with only face the faces that use this material.
			faces can be any iterable object - containing ints.
			'''
			
			faceVertUsers = [False] * len(myContextMesh_vertls)
			ok=0
			for fIdx in faces:
				for vindex in myContextMesh_facels[fIdx]:
					faceVertUsers[vindex] = True
					if matName != None: # if matName is none then this is a set(), meaning we are using the untextured faces and do not need to store textured faces.
						materialFaces.add(fIdx)
					ok=1
			
			if not ok:
				return
					
			myVertMapping = {}
			vertMappingIndex = 0
			
			vertsToUse = [i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i]]
			myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
			
			tempName= '%s_%s' % (contextObName, matName) # matName may be None.
			bmesh = bpy.data.meshes.new(tempName)
			
			if matName == None:
				img= None
			else:
				bmat = MATDICT[matName][1]
				bmesh.materials= [bmat]
				try:	img= TEXTURE_DICT[bmat.name]
				except:	img= None
				
			bmesh_verts = bmesh.verts
			bmesh_verts.extend( [Vector()] )
			bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
			# +1 because of DUMMYVERT
			face_mapping= bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
			
			if bmesh.faces and (contextMeshUV or img):
				bmesh.faceUV= 1
				for ii, i in enumerate(faces):
					
					# Mapped index- faces may have not been added- if so, then map to the correct index
					# BUGGY API - face_mapping is not always the right length
					map_index= face_mapping[ii]
					
					if map_index != None:
						targetFace= bmesh.faces[map_index]
						if contextMeshUV:
							# v.index-1 because of the DUMMYVERT
							targetFace.uv= [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
						if img:
							targetFace.image= img
			
			# bmesh.transform(contextMatrix)
			ob = SCN_OBJECTS.new(bmesh, tempName)
			'''
			if contextMatrix_tx:
				ob.setMatrix(contextMatrix_tx)
			'''
			
			if contextMatrix_rot:
				ob.setMatrix(contextMatrix_rot)
			
			importedObjects.append(ob)
			bmesh.calcNormals()
		
		for matName, faces in myContextMeshMaterials.iteritems():
			makeMeshMaterialCopy(matName, faces)
			
		if len(materialFaces)!=len(myContextMesh_facels):
			# Invert material faces.
			makeMeshMaterialCopy(None, set(range(len( myContextMesh_facels ))) - materialFaces)
			#raise 'Some UnMaterialed faces', len(contextMesh.faces)
	
	#a spare chunk
	new_chunk= chunk()
	temp_chunk= chunk()
	
	CreateBlenderObject = False

	#loop through all the data for this chunk (previous chunk) and see what it is
	while (previous_chunk.bytes_read<previous_chunk.length):
		#print '\t', previous_chunk.bytes_read, 'keep going'
		#read the next chunk
		#print 'reading a chunk'
		read_chunk(file, new_chunk)

		#is it a Version chunk?
		if (new_chunk.ID==VERSION):
			#print 'if (new_chunk.ID==VERSION):'
			#print 'found a VERSION chunk'
			#read in the version of the file
			#it's an unsigned short (H)
			temp_data= file.read(calcsize('I'))
			version = unpack('<I', temp_data)[0]
			new_chunk.bytes_read+= 4 #read the 4 bytes for the version number
			#this loader works with version 3 and below, but may not with 4 and above
			if (version>3):
				print '\tNon-Fatal Error:  Version greater than 3, may not load correctly: ', version

		#is it an object info chunk?
		elif (new_chunk.ID==OBJECTINFO):
			#print 'elif (new_chunk.ID==OBJECTINFO):'
			# print 'found an OBJECTINFO chunk'
			process_next_chunk(file, new_chunk, importedObjects, IMAGE_SEARCH)
			
			#keep track of how much we read in the main chunk
			new_chunk.bytes_read+=temp_chunk.bytes_read

		#is it an object chunk?
		elif (new_chunk.ID==OBJECT):
			
			if CreateBlenderObject:
				putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
				contextMesh_vertls= []; contextMesh_facels= []
			
				## preparando para receber o proximo objeto
				contextMeshMaterials= {} # matname:[face_idxs]
				contextMeshUV= None
				#contextMesh.vertexUV= 1 # Make sticky coords.
				# Reset matrix
				contextMatrix_rot= None
				#contextMatrix_tx= None
				
			CreateBlenderObject= True
			tempName= read_string(file)
			contextObName= tempName
			new_chunk.bytes_read += len(tempName)+1
		
		#is it a material chunk?
		elif (new_chunk.ID==MATERIAL):
			#print 'elif (new_chunk.ID==MATERIAL):'
			contextMaterial= bpy.data.materials.new('Material')
		
		elif (new_chunk.ID==MAT_NAME):
			#print 'elif (new_chunk.ID==MAT_NAME):'
			material_name= read_string(file)
			
			#plus one for the null character that ended the string
			new_chunk.bytes_read+= len(material_name)+1
			
			contextMaterial.name= material_name.rstrip() # remove trailing  whitespace
			MATDICT[material_name]= (contextMaterial.name, contextMaterial)
		
		elif (new_chunk.ID==MAT_AMBIENT):
			#print 'elif (new_chunk.ID==MAT_AMBIENT):'
			read_chunk(file, temp_chunk)
			if (temp_chunk.ID==MAT_FLOAT_COLOR):
				temp_data=file.read(calcsize('3f'))
				temp_chunk.bytes_read+=12
				contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)]
			elif (temp_chunk.ID==MAT_24BIT_COLOR):
				temp_data=file.read(calcsize('3B'))
				temp_chunk.bytes_read+= 3
				contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
			else:
				skip_to_end(file, temp_chunk)
			new_chunk.bytes_read+= temp_chunk.bytes_read

		elif (new_chunk.ID==MAT_DIFFUSE):
			#print 'elif (new_chunk.ID==MAT_DIFFUSE):'
			read_chunk(file, temp_chunk)
			if (temp_chunk.ID==MAT_FLOAT_COLOR):
				temp_data=file.read(calcsize('3f'))
				temp_chunk.bytes_read+=12
				contextMaterial.rgbCol=[float(col) for col in unpack('<3f', temp_data)]
			elif (temp_chunk.ID==MAT_24BIT_COLOR):
				temp_data=file.read(calcsize('3B'))
				temp_chunk.bytes_read+= 3
				contextMaterial.rgbCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
			else:
				skip_to_end(file, temp_chunk)
			new_chunk.bytes_read+= temp_chunk.bytes_read

		elif (new_chunk.ID==MAT_SPECULAR):
			#print 'elif (new_chunk.ID==MAT_SPECULAR):'
			read_chunk(file, temp_chunk)
			if (temp_chunk.ID==MAT_FLOAT_COLOR):
				temp_data=file.read(calcsize('3f'))
				temp_chunk.bytes_read+=12
				contextMaterial.mirCol=[float(col) for col in unpack('<3f', temp_data)]
			elif (temp_chunk.ID==MAT_24BIT_COLOR):
				temp_data=file.read(calcsize('3B'))
				temp_chunk.bytes_read+= 3
				contextMaterial.mirCol= [float(col)/255 for col in unpack('<3B', temp_data)] # data [0,1,2] == rgb
			else:
				skip_to_end(file, temp_chunk)
			new_chunk.bytes_read+= temp_chunk.bytes_read
			
		elif (new_chunk.ID==MAT_TEXTURE_MAP):
			#print 'elif (new_chunk.ID==MAT_TEXTURE_MAP):'
			new_texture= bpy.data.textures.new('Diffuse')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				#print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name=read_string(file)
					#img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
					
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+= temp_chunk.bytes_read
			
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'DIFFUSE')
			
		elif (new_chunk.ID==MAT_SPECULAR_MAP):
			#print 'elif (new_chunk.ID==MAT_SPECULAR_MAP):'
			new_texture= bpy.data.textures.new('Specular')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name= read_string(file)
					#img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read+= (len(texture_name)+1) #plus one for the null character that gets removed
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+= temp_chunk.bytes_read
				
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'SPECULAR')
	
		elif (new_chunk.ID==MAT_OPACITY_MAP):
			#print 'new_texture=Blender.Texture.New('Opacity')'
			new_texture= bpy.data.textures.new('Opacity')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name= read_string(file)
					#img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+= temp_chunk.bytes_read
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'OPACITY')

		elif (new_chunk.ID==MAT_BUMP_MAP):
			#print 'elif (new_chunk.ID==MAT_BUMP_MAP):'
			new_texture= bpy.data.textures.new('Bump')
			new_texture.setType('Image')
			img = None
			while (new_chunk.bytes_read<new_chunk.length):
				read_chunk(file, temp_chunk)
				
				if (temp_chunk.ID==MAT_MAP_FILENAME):
					texture_name= read_string(file)
					#img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
					img= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
					new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
				else:
					skip_to_end(file, temp_chunk)
				
				new_chunk.bytes_read+=temp_chunk.bytes_read
				
			#add the map to the material in the right channel
			if img:
				add_texture_to_material(img, new_texture, contextMaterial, 'BUMP')
			
		elif (new_chunk.ID==MAT_TRANSPARENCY):
			#print 'elif (new_chunk.ID==MAT_TRANSPARENCY):'
			read_chunk(file, temp_chunk)
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			
			temp_chunk.bytes_read+=2
			contextMaterial.alpha= 1-(float(unpack('<H', temp_data)[0])/100)
			new_chunk.bytes_read+=temp_chunk.bytes_read


		elif (new_chunk.ID==OBJECT_LAMP): # Basic lamp support.
			
			temp_data=file.read(STRUCT_SIZE_3FLOAT)
			
			x,y,z=unpack('<3f', temp_data)
			new_chunk.bytes_read+=STRUCT_SIZE_3FLOAT
			
			contextLamp[1]= bpy.data.lamps.new()
			contextLamp[0]= SCN_OBJECTS.new(contextLamp[1])
			importedObjects.append(contextLamp[0])
			
			#print 'number of faces: ', num_faces
			#print x,y,z
			contextLamp[0].setLocation(x,y,z)
			
			# Reset matrix
			contextMatrix_rot= None
			#contextMatrix_tx= None
			#print contextLamp.name, 
			
		elif (new_chunk.ID==OBJECT_MESH):
			# print 'Found an OBJECT_MESH chunk'
			pass
		elif (new_chunk.ID==OBJECT_VERTICES):
			'''
			Worldspace vertex locations
			'''
			# print 'elif (new_chunk.ID==OBJECT_VERTICES):'
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_verts=unpack('<H', temp_data)[0]
			new_chunk.bytes_read+=2
			
			# print 'number of verts: ', num_verts
			def getvert():
				temp_data= unpack('<3f', file.read(STRUCT_SIZE_3FLOAT))
				new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each
				return temp_data
			
			#contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed.
			contextMesh_vertls= [getvert() for i in xrange(num_verts)]
			
			#print 'object verts: bytes read: ', new_chunk.bytes_read

		elif (new_chunk.ID==OBJECT_FACES):
			# print 'elif (new_chunk.ID==OBJECT_FACES):'
			temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_faces= unpack('<H', temp_data)[0]
			new_chunk.bytes_read+= 2
			#print 'number of faces: ', num_faces
			
			def getface():
				# print '\ngetting a face'
				temp_data= file.read(STRUCT_SIZE_4UNSIGNED_SHORT)
				new_chunk.bytes_read+= STRUCT_SIZE_4UNSIGNED_SHORT #4 short ints x 2 bytes each
				v1,v2,v3,dummy= unpack('<4H', temp_data)
				return v1, v2, v3
			
			contextMesh_facels= [ getface() for i in xrange(num_faces) ]


		elif (new_chunk.ID==OBJECT_MATERIAL):
			# print 'elif (new_chunk.ID==OBJECT_MATERIAL):'
			material_name= read_string(file)
			new_chunk.bytes_read += len(material_name)+1 # remove 1 null character.
			
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_faces_using_mat = unpack('<H', temp_data)[0]
			new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
			
			def getmat():
				temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
				new_chunk.bytes_read+= STRUCT_SIZE_UNSIGNED_SHORT
				return unpack('<H', temp_data)[0]
			
			contextMeshMaterials[material_name]= [ getmat() for i in xrange(num_faces_using_mat) ]
			
			#look up the material in all the materials

		elif (new_chunk.ID==OBJECT_UV):
			temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
			num_uv=unpack('<H', temp_data)[0]
			new_chunk.bytes_read+= 2
			
			def getuv():
				temp_data=file.read(STRUCT_SIZE_2FLOAT)
				new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each
				return Vector( unpack('<2f', temp_data) )
				
			contextMeshUV= [ getuv() for i in xrange(num_uv) ]
		
		elif (new_chunk.ID== OBJECT_TRANS_MATRIX):
			# How do we know the matrix size? 54 == 4x4 48 == 4x3
			temp_data=file.read(STRUCT_SIZE_4x3MAT)
			data= list( unpack('<ffffffffffff', temp_data)  )
			new_chunk.bytes_read += STRUCT_SIZE_4x3MAT
			
			contextMatrix_rot= Blender.Mathutils.Matrix(\
			 data[:3] + [0],\
			 data[3:6] + [0],\
			 data[6:9] + [0],\
			 data[9:] + [1])
			
			
			'''
			contextMatrix_rot= Blender.Mathutils.Matrix(\
			 data[:3] + [0],\
			 data[3:6] + [0],\
			 data[6:9] + [0],\
			 [0,0,0,1])
			'''
			
			'''
			contextMatrix_rot= Blender.Mathutils.Matrix(\
			 data[:3] ,\
			 data[3:6],\
			 data[6:9])
			'''
			
			'''
			contextMatrix_rot = Blender.Mathutils.Matrix()
			m = 0
			for j in xrange(4):
				for i in xrange(3):
					contextMatrix_rot[j][i] = data[m]
					m+=1
			
			contextMatrix_rot[0][3]=0;
			contextMatrix_rot[1][3]=0;
			contextMatrix_rot[2][3]=0;
			contextMatrix_rot[3][3]=1;
			'''
			
			#contextMatrix_rot.resize4x4()
			#print "MTX"
			#print contextMatrix_rot
			contextMatrix_rot.invert()
			#print contextMatrix_rot
			#contextMatrix_tx = Blender.Mathutils.TranslationMatrix(0.5 * Blender.Mathutils.Vector(data[9:]))
			#contextMatrix_tx.invert()
			
			#tx.invert()
			
			#contextMatrix = contextMatrix * tx
			#contextMatrix = contextMatrix  *tx
			
		elif  (new_chunk.ID==MAT_MAP_FILENAME):
			texture_name=read_string(file)
			try:
				TEXTURE_DICT[contextMaterial.name]
			except:
				#img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
				img= TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
			
			new_chunk.bytes_read+= len(texture_name)+1 #plus one for the null character that gets removed
		
		else: #(new_chunk.ID!=VERSION or new_chunk.ID!=OBJECTINFO or new_chunk.ID!=OBJECT or new_chunk.ID!=MATERIAL):
			# print 'skipping to end of this chunk'
			buffer_size=new_chunk.length-new_chunk.bytes_read
			binary_format='%ic' % buffer_size
			temp_data=file.read(calcsize(binary_format))
			new_chunk.bytes_read+=buffer_size


		#update the previous chunk bytes read
		# print 'previous_chunk.bytes_read += new_chunk.bytes_read'
		# print previous_chunk.bytes_read, new_chunk.bytes_read
		previous_chunk.bytes_read += new_chunk.bytes_read
		## print 'Bytes left in this chunk: ', previous_chunk.length-previous_chunk.bytes_read
	
	# FINISHED LOOP
	# There will be a number of objects still not added
	if contextMesh_facels != None:
		putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)