diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py index b5c307f7a06..673994400d1 100644 --- a/release/scripts/3ds_import.py +++ b/release/scripts/3ds_import.py @@ -17,6 +17,11 @@ This script imports a 3ds file and the materials into Blender for editing. Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen). +0.94 by Campbell Barton
+- Face import tested to be about overall 16x speedup over 0.93. +- Material importing speedup. +- Tested with more models. +- Support some corrupt models. 0.93 by Campbell Barton
- Tested with 400 3ds files from turbosquid and samples. @@ -272,8 +277,8 @@ def add_texture_to_material(image, texture, material, mapto): if index>10: print "/tError: Cannot add diffuse map. Too many textures" -def process_next_chunk(file, filename, previous_chunk): - scn = Scene.GetCurrent() +def process_next_chunk(file, filename, previous_chunk, scn): + #print previous_chunk.bytes_read, "BYTES READ" contextObName = None contextLamp = [None, None] # object, Data contextMaterial = None @@ -295,6 +300,7 @@ def process_next_chunk(file, filename, previous_chunk): def putContextMesh(myContextMesh): + #print 'prtting myContextMesh', myContextMesh.name INV_MAT = Blender.Mathutils.Matrix(contextMatrix) INV_MAT.invert() @@ -318,8 +324,8 @@ def process_next_chunk(file, filename, previous_chunk): objectList.append(newOb) # last 2 recal normals newOb.setMatrix(contextMatrix) - Blender.Window.EditMode(1) - Blender.Window.EditMode(0) + #Blender.Window.EditMode(1) + #Blender.Window.EditMode(0) #a spare chunk @@ -328,12 +334,14 @@ def process_next_chunk(file, filename, previous_chunk): #loop through all the data for this chunk (previous chunk) and see what it is while (previous_chunk.bytes_read= 15: - print "\tCant assign more than 16 materials per mesh, keep going..." + msh_materials = contextMesh.materials + + if mat: + meshHasMat = 0 + for i, myMat in enumerate(msh_materials): + if myMat.name == mat_name: + meshHasMat = 1 + mat_index = i break + + if not meshHasMat: + + if len(msh_materials) > 15: + print "\tCant assign more than 16 materials per mesh, keep going..." + material_found = 0 else: - meshHasMat = 0 - for myMat in contextMesh.materials: - if myMat.name == mat.name: - meshHasMat = 1 - - if meshHasMat == 0: - contextMesh.materials = contextMesh.materials + [mat] - material_found=1 - - #figure out what material index this is for the mesh - for mat_counter in xrange(len(contextMesh.materials)): - if contextMesh.materials[mat_counter].name == material_name: - mat_index=mat_counter - #print "material index: ",mat_index - - - break # get out of this for loop so we don't accidentally set material_found back to 0 - else: - material_found=0 - # print "Not matching: ", mat.name, " and ", material_name + mat_index = len(msh_materials) + contextMesh.materials = msh_materials + [mat] + material_found=1 + else: + material_found=0 + # print "Not matching: ", mat.name, " and ", material_name #print contextMesh.materials if material_found == 1: contextMaterial = mat @@ -654,26 +661,32 @@ def process_next_chunk(file, filename, previous_chunk): new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT num_faces_using_mat=data[0] + try: + img = TEXTURE_DICT[ MATDICT[contextMaterial.name][0] ] + contextMesh.faceUV = 1 + except KeyError: + img = None + + #list of faces using mat for face_counter in xrange(num_faces_using_mat): temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT) new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT data=struct.unpack("H", temp_data) - facemap = contextFaceMapping[data[0]] - if facemap != None: # Face map can be None when teh face has bad data. - face = contextMesh.faces[facemap] + + # We dont have to use context face mapping. + if contextFaceMapping: + facemap= contextFaceMapping[data[0]] + if facemap != None: + face= contextMesh.faces[contextFaceMapping[data[0]]] + else: + face= None + else: + face = contextMesh.faces[data[0]] + + if face: face.mat = mat_index - - - mname = MATDICT[contextMaterial.name] - - try: - img = TEXTURE_DICT[mname] - except: - img = None - if img: - contextMesh.faceUV = 1 #print 'Assigning image', img.name face.mode |= TEXMODE face.image = img @@ -689,11 +702,12 @@ def process_next_chunk(file, filename, previous_chunk): #print "object mat: bytes read: ", new_chunk.bytes_read elif (new_chunk.ID == OBJECT_UV): - # print "Found an OBJECT_UV chunk" + # print "elif (new_chunk.ID == OBJECT_UV):" temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT) data=struct.unpack("H", temp_data) new_chunk.bytes_read+=2 num_uv=data[0] + def getuv(): temp_data=file.read(STRUCT_SIZE_2FLOAT) new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each @@ -701,19 +715,9 @@ def process_next_chunk(file, filename, previous_chunk): return Vector(data[0], data[1]) contextMeshUV = [ getuv() for i in xrange(num_uv) ] - ''' - for counter in xrange(num_uv): - temp_data=file.read(STRUCT_SIZE_2FLOAT) - new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each - data=struct.unpack("2f", temp_data) - - #insert the insert the UV coords in the vertex data - contextMeshUV[counter].uvco = data - ''' elif (new_chunk.ID == OBJECT_TRANS_MATRIX): - # print "Found an OBJECT_TRANS_MATRIX chunk" - + # print "elif (new_chunk.ID == OBJECT_TRANS_MATRIX):" temp_data=file.read(STRUCT_SIZE_4x3MAT) data = list( struct.unpack("ffffffffffff", temp_data) ) new_chunk.bytes_read += STRUCT_SIZE_4x3MAT @@ -735,8 +739,10 @@ def process_next_chunk(file, filename, previous_chunk): #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 + ## 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 @@ -749,8 +755,8 @@ def process_next_chunk(file, filename, previous_chunk): def load_3ds(filename): print '\n\nImporting "%s"' % filename - # - for ob in Scene.GetCurrent().getChildren(): + scn = Scene.GetCurrent() + for ob in scn.getChildren(): ob.sel = 0 time1 = Blender.sys.time() @@ -768,14 +774,13 @@ def load_3ds(filename): file.close() return - process_next_chunk(file, filename, current_chunk) + process_next_chunk(file, filename, current_chunk, scn) # Select all new objects. print 'finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1)) file.close() - if __name__ == '__main__': Blender.Window.FileSelector(load_3ds, "Import 3DS", '*.3ds') @@ -784,17 +789,20 @@ if __name__ == '__main__': """ TIME = Blender.sys.time() import os +print "Searching for files" os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list') +print "Done" file = open('/tmp/temp3ds_list', 'r') -lines = file.readlines()[200:] -file.close() +lines = file.readlines() +file.close() for i, _3ds in enumerate(lines): - _3ds= _3ds[:-1] - print "Importing", _3ds, i - _3ds_file = _3ds.split('/')[-1].split('\\')[-1] - newScn = Scene.New(_3ds_file) - newScn.makeCurrent() - my_callback(_3ds) + if i > 817: + _3ds= _3ds[:-1] + print "Importing", _3ds, '\nNUMBER', i, 'of', len(lines) + _3ds_file = _3ds.split('/')[-1].split('\\')[-1] + newScn = Scene.New(_3ds_file) + newScn.makeCurrent() + load_3ds(_3ds) print "TOTAL TIME: %.6f" % (Blender.sys.time() - TIME) """ \ No newline at end of file