From 62b8cad6608eb568eb39a8ad734c736711e9c6e4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Aug 2006 09:10:06 +0000 Subject: [PATCH] simplified 3ds mesh importing by storing verts and faces in a list rather then a mesh, before making the final mesh also make use of meshes faces.extend() indexList option- which means lots of checking can be removed. indexList is not relyable at the moment so some files wont import but this will be fixed. --- release/scripts/3ds_import.py | 197 +++++++++++++++++----------------- 1 file changed, 97 insertions(+), 100 deletions(-) diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py index c78c4e280ed..5cb40423712 100644 --- a/release/scripts/3ds_import.py +++ b/release/scripts/3ds_import.py @@ -297,7 +297,8 @@ def process_next_chunk(file, previous_chunk, importedObjects): contextLamp= [None, None] # object, Data contextMaterial= None contextMatrix= Blender.Mathutils.Matrix(); contextMatrix.identity() - contextMesh= None + contextMesh_vertls= None + contextMesh_facels= None contextMeshMaterials= {} # matname:[face_idxs] TEXTURE_DICT={} @@ -313,10 +314,20 @@ def process_next_chunk(file, previous_chunk, importedObjects): STRUCT_SIZE_4x3MAT= calcsize('ffffffffffff') - def putContextMesh(myContextMesh, myContextMeshMaterials): - contextMesh.transform(contextMatrix.inverted()) + def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials): + ####contextMesh.transform(contextMatrix.copy().invert()) - materialFaces= set() + # Copy UV's to mesh + """ + if contextMeshUV: + myContextMesh.faceUV= 1 + for f in myContextMesh.faces: + # v.index-1 because of the DUMMYVERT + f.uv= [contextMeshUV[v.index-1] for v in f] + """ + + materialFaces= set() # faces that have a material. Can optimize + allFaces= set(range(len( myContextMesh_facels ))) # Now make copies with assigned materils. def makeMeshMaterialCopy(matName, faces): @@ -324,11 +335,12 @@ def process_next_chunk(file, previous_chunk, importedObjects): 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.verts) + + faceVertUsers = [False] * len(myContextMesh_vertls) ok=0 for fIdx in faces: - for v in myContextMesh.faces[fIdx].v: - faceVertUsers[v.index] = True + 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 @@ -339,10 +351,11 @@ def process_next_chunk(file, previous_chunk, importedObjects): myVertMapping = {} vertMappingIndex = 0 - vertsToUse = [i for i in xrange(len(myContextMesh.verts)) if faceVertUsers[i]] + vertsToUse = [i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i]] myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] ) - bmesh = Mesh.New(contextMesh.name) + ##bmesh = Mesh.New(contextMesh.name) + bmesh = Mesh.New() if matName != None: bmat = MATDICT[matName][1] @@ -353,35 +366,47 @@ def process_next_chunk(file, previous_chunk, importedObjects): bmesh.materials= [bmat] else: img= None - + bmesh.verts.extend( [Vector()] ) - bmesh.verts.extend( [myContextMesh.verts[i].co for i in vertsToUse] ) + bmesh.verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] ) # +1 because of DUMMYVERT - bmesh.faces.extend( [ [ bmesh.verts[ myVertMapping[v.index]+1] for v in myContextMesh.faces[fIdx].v] for fIdx in faces ] ) + ###bmesh.faces.extend( [ [ bmesh.verts[ myVertMapping[v.index]+1] for v in myContextMesh.faces[fIdx].v] for fIdx in faces ] ) + face_mapping= bmesh.faces.extend( [ [ bmesh.verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True ) + print len(face_mapping), len(faces) + + if len(face_mapping) == len(faces): + print face_mapping if contextMeshUV or img: bmesh.faceUV= 1 for ii, i in enumerate(faces): - targetFace= bmesh.faces[ii] - if contextMeshUV: - # v.index-1 because of the DUMMYVERT - targetFace.uv= [contextMeshUV[v.index-1] for v in myContextMesh.faces[i].v] - if img: - targetFace.image= img + + # 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 tempName= contextObName + '_' + str(matName) # str because we may be None bmesh.name= tempName ob = Object.New('Mesh', tempName) ob.link(bmesh) - ob.setMatrix(contextMatrix) + ####ob.setMatrix(contextMatrix) importedObjects.append(ob) + for matName, faces in myContextMeshMaterials.iteritems(): makeMeshMaterialCopy(matName, faces) - if len(materialFaces)!=len(contextMesh.faces): + if len(materialFaces)!=len(myContextMesh_facels): # Invert material faces. - makeMeshMaterialCopy(None, set(range(len( contextMesh.faces ))) - materialFaces) + makeMeshMaterialCopy(None, allFaces - materialFaces) #raise 'Some UnMaterialed faces', len(contextMesh.faces) @@ -579,10 +604,12 @@ def process_next_chunk(file, previous_chunk, importedObjects): elif (new_chunk.ID==OBJECT_MESH): # print 'Found an OBJECT_MESH chunk' - if contextMesh != None: # Write context mesh if we have one. - putContextMesh(contextMesh, contextMeshMaterials) + if contextMesh_facels != None: # Write context mesh if we have one. + putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials) - contextMesh= Mesh.New() + #contextMesh= Mesh.New() + contextMesh_vertls= [] + contextMesh_facels= [] contextMeshMaterials= {} # matname:[face_idxs] contextMeshUV= None #contextMesh.vertexUV= 1 # Make sticky coords. @@ -615,10 +642,11 @@ def process_next_chunk(file, previous_chunk, importedObjects): new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each - return Vector(temp_data) + return temp_data + + #contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed. + contextMesh_vertls= [getvert() for i in xrange(num_verts)] - contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed. - contextMesh.verts.extend( [getvert() for i in xrange(num_verts)] ) #print 'object verts: bytes read: ', new_chunk.bytes_read elif (new_chunk.ID==OBJECT_FACES): @@ -633,46 +661,12 @@ def process_next_chunk(file, previous_chunk, importedObjects): 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) - if v1==v2 or v1==v3 or v2==v3: - return None + ##if v1==v2 or v1==v3 or v2==v3: + ## return None # DUMMYVERT! - remove +1 when blenders internals are fixed, - return contextMesh.verts[v1+1], contextMesh.verts[v2+1], contextMesh.verts[v3+1] + return v1, v2, v3 - faces= [ getface() for i in xrange(num_faces) ] - facesExtend= [ f for f in faces if f ] - - if facesExtend: - contextMesh.faces.extend( facesExtend ) - - # face mapping so duplicate faces dont mess us up. - if len(contextMesh.faces)==len(faces): - contextFaceMapping= None - else: - contextFaceMapping= {} - meshFaceOffset= 0 - for i, f in enumerate(faces): - if not f: # Face used stupid verts- - contextFaceMapping[i]= None - meshFaceOffset+= 1 - else: - #print 'DOUBLE FACE', '\tfacelen', len(f), i, num_faces, (i-meshFaceOffset) - #print i-meshFaceOffset, len(contextMesh.faces)q - if len(contextMesh.faces) <= i-meshFaceOffset: # SHOULD NEVER HAPPEN, CORRUPS 3DS? - contextFaceMapping[i]= None - meshFaceOffset-=1 - else: - meshface= contextMesh.faces[i-meshFaceOffset] - ok= True - for vi in xrange(len(f)): - if meshface.v[vi] != f[vi]: - ok=False - break - if ok: - meshFaceOffset+=1 - contextFaceMapping[i]= i-meshFaceOffset - else: - contextFaceMapping[i]= None - + contextMesh_facels= [ getface() for i in xrange(num_faces) ] elif (new_chunk.ID==OBJECT_MATERIAL): @@ -680,7 +674,7 @@ def process_next_chunk(file, previous_chunk, importedObjects): material_name= read_string(file) new_chunk.bytes_read += len(material_name)+1 # remove 1 null character. - tempMatFaceIndexList = contextMeshMaterials[material_name]= [] + tempMatFaceIndexList = contextMeshMaterials[material_name]= set() temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT) num_faces_using_mat,= unpack(' /tmp/temp3ds_list') -# os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list') -print '...Done' -file= open('/tmp/temp3ds_list', 'r') -lines= file.readlines() -file.close() +else: + # DEBUG ONLY + TIME= Blender.sys.time() + import os + print 'Searching for files' + os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list') + # os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list') + print '...Done' + file= open('/tmp/temp3ds_list', 'r') + lines= file.readlines() + file.close() -def between(v,a,b): - if v <= max(a,b) and v >= min(a,b): - return True - return False - -for i, _3ds in enumerate(lines): - if between(i, 1, 200): - _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, False) + def between(v,a,b): + if v <= max(a,b) and v >= min(a,b): + return True + return False + + for i, _3ds in enumerate(lines): + if between(i, 1, 40): + _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, False) + + print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) -print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) -'''