[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31272] trunk/blender/release/scripts/io: [#23275] .3DS import script fails on some models.
Campbell Barton
ideasman42 at gmail.com
Thu Aug 12 04:24:13 CEST 2010
Revision: 31272
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31272
Author: campbellbarton
Date: 2010-08-12 04:24:12 +0200 (Thu, 12 Aug 2010)
Log Message:
-----------
[#23275] .3DS import script fails on some models.
- fixed reading meshes without faces.
also changed...
- read verts/faces/uvs in one struct.unpack(), should be a bit faster.
- removed mesh/material splitting, very confusing/slow code and not needed since the 16 material limit was removed.
- load image paths with bpy.path.resolve_ncase() since many 3ds's files has case mismatch with file names (applies to OBJ too).
Modified Paths:
--------------
trunk/blender/release/scripts/io/import_scene_3ds.py
trunk/blender/release/scripts/io/import_scene_obj.py
Modified: trunk/blender/release/scripts/io/import_scene_3ds.py
===================================================================
--- trunk/blender/release/scripts/io/import_scene_3ds.py 2010-08-12 01:05:11 UTC (rev 31271)
+++ trunk/blender/release/scripts/io/import_scene_3ds.py 2010-08-12 02:24:12 UTC (rev 31272)
@@ -141,7 +141,7 @@
import time
import struct
-from import_scene_obj import unpack_face_list, load_image
+from import_scene_obj import load_image
import bpy
import mathutils
@@ -312,10 +312,10 @@
contextMaterial = None
contextMatrix_rot = None # Blender.mathutils.Matrix(); contextMatrix.identity()
#contextMatrix_tx = None # Blender.mathutils.Matrix(); contextMatrix.identity()
- contextMesh_vertls = None
+ contextMesh_vertls = None # flat array: (verts * 3)
contextMesh_facels = None
contextMeshMaterials = {} # matname:[face_idxs]
- contextMeshUV = None
+ contextMeshUV = None # flat array (verts * 2)
TEXTURE_DICT = {}
MATDICT = {}
@@ -333,114 +333,70 @@
# print STRUCT_SIZE_4x3MAT, ' STRUCT_SIZE_4x3MAT'
def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
+
+ bmesh = bpy.data.meshes.new(contextObName)
+ if myContextMesh_vertls:
- 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 range(len(myContextMesh_vertls)) if faceVertUsers[i]]
- myVertMapping = {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
+ bmesh.add_geometry(len(myContextMesh_vertls)//3, 0, len(myContextMesh_facels))
+ bmesh.verts.foreach_set("co", myContextMesh_vertls)
+
+ eekadoodle_faces = []
+ for v1, v2, v3 in myContextMesh_facels:
+ eekadoodle_faces.extend([v3, v1, v2, 0] if v3 == 0 else [v1, v2, v3, 0])
+ bmesh.faces.foreach_set("verts_raw", eekadoodle_faces)
+
+ if bmesh.faces and contextMeshUV:
+ bmesh.add_uv_texture()
+ uv_faces = bmesh.active_uv_texture.data[:]
else:
- bmat = MATDICT[matName][1]
- bmesh.add_material(bmat)
-# bmesh.materials = [bmat]
- try: img = TEXTURE_DICT[bmat.name]
- except: img = None
+ uv_faces = None
-# bmesh_verts = bmesh.verts
- if len(vertsToUse):
- bmesh.add_geometry(len(vertsToUse), 0, len(faces))
+ for mat_idx, (matName, faces) in enumerate(myContextMeshMaterials.items()):
+ if matName is None:
+ bmesh.add_material(None)
+ else:
+ bmat = MATDICT[matName][1]
+ bmesh.add_material(bmat) # can be None
+ img = TEXTURE_DICT.get(bmat.name)
+
+ if uv_faces and img:
+ for fidx in faces:
+ bmesh.faces[fidx].material_index = mat_idx
+ uf = uv_faces[fidx]
+ uf.image = img
+ uf.tex = True
+ else:
+ for fidx in faces:
+ bmesh.faces[fidx].material_index = mat_idx
+
+ if uv_faces:
+ for fidx, uf in enumerate(uv_faces):
+ face = myContextMesh_facels[fidx]
+ v1, v2, v3 = face
+
+ # eekadoodle
+ if v3 == 0:
+ v1, v2, v3 = v3, v1, v2
+
+ uf.uv1 = contextMeshUV[v1 * 2:(v1 * 2) + 2]
+ uf.uv2 = contextMeshUV[v2 * 2:(v2 * 2) + 2]
+ uf.uv3 = contextMeshUV[v3 * 2:(v3 * 2) + 2]
+ # always a tri
- # XXX why add extra vertex?
-# bmesh_verts.extend( [Vector()] )
- bmesh.verts.foreach_set("co", [x for tup in [myContextMesh_vertls[i] for i in vertsToUse] for x in tup])
-# bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
+ ob = bpy.data.objects.new(tempName, bmesh)
+ SCN.objects.link(ob)
+
+ '''
+ if contextMatrix_tx:
+ ob.setMatrix(contextMatrix_tx)
+ '''
+
+ if contextMatrix_rot:
+ ob.matrix_world = contextMatrix_rot
- # +1 because of DUMMYVERT
- bmesh.faces.foreach_set("verts_raw", unpack_face_list([[myVertMapping[vindex] for vindex in myContextMesh_facels[fIdx]] 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 )
+ importedObjects.append(ob)
+ bmesh.update()
- if bmesh.faces and (contextMeshUV or img):
- bmesh.add_uv_texture()
- 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 1:
-# if map_index != None:
- targetFace = bmesh.faces[ii]
-# targetFace = bmesh.faces[map_index]
-
- uf = bmesh.active_uv_texture.data[ii]
-
- if contextMeshUV:
- # v.index-1 because of the DUMMYVERT
- uvs = [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
-
- if len(myContextMesh_facels[i]) == 3:
- uf.uv1, uf.uv2, uf.uv3, uf.uv4 = uvs + [(0.0, 0.0)]
- else:
- uf.uv1, uf.uv2, uf.uv3, uf.uv4 = uvs
-# targetFace.uv = [contextMeshUV[vindex] for vindex in myContextMesh_facels[i]]
- if img:
- uf.image = img
-
- # to get this image to show up in 'Textured' shading mode
- uf.tex = True
-
- # bmesh.transform(contextMatrix)
- ob = bpy.data.objects.new(tempName, bmesh)
- SCN.objects.link(ob)
-# ob = SCN_OBJECTS.new(bmesh, tempName)
- '''
- if contextMatrix_tx:
- ob.setMatrix(contextMatrix_tx)
- '''
-
- if contextMatrix_rot:
- ob.matrix_world = contextMatrix_rot
-
- importedObjects.append(ob)
- bmesh.update()
-# bmesh.calcNormals()
-
- for matName, faces in myContextMeshMaterials.items():
- 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()
@@ -667,14 +623,10 @@
new_chunk.bytes_read += 2
# print 'number of verts: ', num_verts
- def getvert():
- temp_data = struct.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 range(num_verts)]
-
+ contextMesh_vertls = struct.unpack('<%df' % (num_verts * 3), file.read(STRUCT_SIZE_3FLOAT * num_verts))
+ new_chunk.bytes_read += STRUCT_SIZE_3FLOAT * num_verts
+ # dummyvert is not used atm!
+
#print 'object verts: bytes read: ', new_chunk.bytes_read
elif (new_chunk.ID == OBJECT_FACES):
@@ -684,16 +636,12 @@
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 = struct.unpack('<4H', temp_data)
- return v1, v2, v3
+ # print '\ngetting a face'
+ temp_data = file.read(STRUCT_SIZE_4UNSIGNED_SHORT * num_faces)
+ new_chunk.bytes_read += STRUCT_SIZE_4UNSIGNED_SHORT * num_faces #4 short ints x 2 bytes each
+ contextMesh_facels = struct.unpack('<%dH' % (num_faces * 4), temp_data)
+ contextMesh_facels = [contextMesh_facels[i - 3:i] for i in range(3, (num_faces * 4) + 3, 4)]
- contextMesh_facels = [ getface() for i in range(num_faces) ]
-
-
elif (new_chunk.ID == OBJECT_MATERIAL):
# print 'elif (new_chunk.ID == OBJECT_MATERIAL):'
material_name = read_string(file)
@@ -703,12 +651,11 @@
num_faces_using_mat = struct.unpack('<H', temp_data)[0]
new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
- def getmat():
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list