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
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
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)