forked from bartvdbraak/blender
cleanup and some speedups with assigning materials
This commit is contained in:
parent
69836ce9bc
commit
e10613c7f7
@ -8,7 +8,7 @@ Tooltip: 'Import from 3DS file format (.3ds)'
|
|||||||
|
|
||||||
__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton']
|
__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton']
|
||||||
__url__= ('blender', 'elysiun', 'http://www.gametutorials.com')
|
__url__= ('blender', 'elysiun', 'http://www.gametutorials.com')
|
||||||
__version__= '0.96'
|
__version__= '0.98'
|
||||||
__bpydoc__= '''\
|
__bpydoc__= '''\
|
||||||
|
|
||||||
3ds Importer
|
3ds Importer
|
||||||
@ -18,6 +18,10 @@ 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).
|
Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen).
|
||||||
|
|
||||||
|
|
||||||
|
0.98 by Campbell Barton<br>
|
||||||
|
- import faces and verts to lists instead of a mesh, convert to a mesh later
|
||||||
|
- use new index mapping feature of mesh to re-map faces that were not added.
|
||||||
|
|
||||||
0.97 by Campbell Barton<br>
|
0.97 by Campbell Barton<br>
|
||||||
- Strip material names of spaces
|
- Strip material names of spaces
|
||||||
- Added import as instance to import the 3ds into its own
|
- Added import as instance to import the 3ds into its own
|
||||||
@ -296,7 +300,7 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
contextObName= None
|
contextObName= None
|
||||||
contextLamp= [None, None] # object, Data
|
contextLamp= [None, None] # object, Data
|
||||||
contextMaterial= None
|
contextMaterial= None
|
||||||
contextMatrix= Blender.Mathutils.Matrix(); contextMatrix.identity()
|
# contextMatrix= Blender.Mathutils.Matrix(); contextMatrix.identity()
|
||||||
contextMesh_vertls= None
|
contextMesh_vertls= None
|
||||||
contextMesh_facels= None
|
contextMesh_facels= None
|
||||||
contextMeshMaterials= {} # matname:[face_idxs]
|
contextMeshMaterials= {} # matname:[face_idxs]
|
||||||
@ -317,17 +321,8 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
|
def putContextMesh(myContextMesh_vertls, myContextMesh_facels, myContextMeshMaterials):
|
||||||
####contextMesh.transform(contextMatrix.copy().invert())
|
####contextMesh.transform(contextMatrix.copy().invert())
|
||||||
|
|
||||||
# Copy UV's to mesh
|
materialFaces= set() # faces that have a material. Can optimize?
|
||||||
"""
|
|
||||||
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.
|
# Now make copies with assigned materils.
|
||||||
|
|
||||||
def makeMeshMaterialCopy(matName, faces):
|
def makeMeshMaterialCopy(matName, faces):
|
||||||
@ -357,25 +352,19 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
##bmesh = Mesh.New(contextMesh.name)
|
##bmesh = Mesh.New(contextMesh.name)
|
||||||
bmesh = Mesh.New()
|
bmesh = Mesh.New()
|
||||||
|
|
||||||
if matName != None:
|
if matName == None:
|
||||||
bmat = MATDICT[matName][1]
|
|
||||||
try:
|
|
||||||
img= TEXTURE_DICT[bmat.name]
|
|
||||||
except:
|
|
||||||
img= None
|
|
||||||
bmesh.materials= [bmat]
|
|
||||||
else:
|
|
||||||
img= None
|
img= None
|
||||||
|
else:
|
||||||
|
bmat = MATDICT[matName][1]
|
||||||
|
bmesh.materials= [bmat]
|
||||||
|
try: img= TEXTURE_DICT[bmat.name]
|
||||||
|
except: img= None
|
||||||
|
|
||||||
|
|
||||||
bmesh.verts.extend( [Vector()] )
|
bmesh.verts.extend( [Vector()] )
|
||||||
bmesh.verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
|
bmesh.verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
|
||||||
# +1 because of DUMMYVERT
|
# +1 because of DUMMYVERT
|
||||||
###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 )
|
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:
|
if contextMeshUV or img:
|
||||||
bmesh.faceUV= 1
|
bmesh.faceUV= 1
|
||||||
@ -393,7 +382,7 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
if img:
|
if img:
|
||||||
targetFace.image= img
|
targetFace.image= img
|
||||||
|
|
||||||
tempName= contextObName + '_' + str(matName) # str because we may be None
|
tempName= '%s_%s' % (contextObName, matName) # matName may be None.
|
||||||
bmesh.name= tempName
|
bmesh.name= tempName
|
||||||
ob = Object.New('Mesh', tempName)
|
ob = Object.New('Mesh', tempName)
|
||||||
ob.link(bmesh)
|
ob.link(bmesh)
|
||||||
@ -406,9 +395,8 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
|
|
||||||
if len(materialFaces)!=len(myContextMesh_facels):
|
if len(materialFaces)!=len(myContextMesh_facels):
|
||||||
# Invert material faces.
|
# Invert material faces.
|
||||||
makeMeshMaterialCopy(None, allFaces - materialFaces)
|
makeMeshMaterialCopy(None, set(range(len( myContextMesh_facels ))) - materialFaces)
|
||||||
#raise 'Some UnMaterialed faces', len(contextMesh.faces)
|
#raise 'Some UnMaterialed faces', len(contextMesh.faces)
|
||||||
|
|
||||||
|
|
||||||
#a spare chunk
|
#a spare chunk
|
||||||
new_chunk= chunk()
|
new_chunk= chunk()
|
||||||
@ -428,7 +416,7 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
#read in the version of the file
|
#read in the version of the file
|
||||||
#it's an unsigned short (H)
|
#it's an unsigned short (H)
|
||||||
temp_data= file.read(calcsize('I'))
|
temp_data= file.read(calcsize('I'))
|
||||||
version,= unpack('<I', temp_data)
|
version = unpack('<I', temp_data)[0]
|
||||||
new_chunk.bytes_read+= 4 #read the 4 bytes for the version number
|
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
|
#this loader works with version 3 and below, but may not with 4 and above
|
||||||
if (version>3):
|
if (version>3):
|
||||||
@ -598,7 +586,7 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
contextLamp[0].setLocation(x,y,z)
|
contextLamp[0].setLocation(x,y,z)
|
||||||
|
|
||||||
# Reset matrix
|
# Reset matrix
|
||||||
contextMatrix= Mathutils.Matrix(); contextMatrix.identity()
|
####contextMatrix= Mathutils.Matrix(); contextMatrix.identity()
|
||||||
#print contextLamp.name,
|
#print contextLamp.name,
|
||||||
|
|
||||||
|
|
||||||
@ -607,14 +595,13 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
if contextMesh_facels != None: # Write context mesh if we have one.
|
if contextMesh_facels != None: # Write context mesh if we have one.
|
||||||
putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
|
putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
|
||||||
|
|
||||||
#contextMesh= Mesh.New()
|
contextMesh_vertls= []; contextMesh_facels= []
|
||||||
contextMesh_vertls= []
|
|
||||||
contextMesh_facels= []
|
|
||||||
contextMeshMaterials= {} # matname:[face_idxs]
|
contextMeshMaterials= {} # matname:[face_idxs]
|
||||||
contextMeshUV= None
|
contextMeshUV= None
|
||||||
#contextMesh.vertexUV= 1 # Make sticky coords.
|
#contextMesh.vertexUV= 1 # Make sticky coords.
|
||||||
# Reset matrix
|
# Reset matrix
|
||||||
contextMatrix= Blender.Mathutils.Matrix(); contextMatrix.identity()
|
####contextMatrix= Blender.Mathutils.Matrix(); contextMatrix.identity()
|
||||||
|
|
||||||
elif (new_chunk.ID==OBJECT_VERTICES):
|
elif (new_chunk.ID==OBJECT_VERTICES):
|
||||||
'''
|
'''
|
||||||
@ -622,25 +609,12 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
'''
|
'''
|
||||||
# print 'elif (new_chunk.ID==OBJECT_VERTICES):'
|
# print 'elif (new_chunk.ID==OBJECT_VERTICES):'
|
||||||
temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
||||||
num_verts,=unpack('<H', temp_data)
|
num_verts=unpack('<H', temp_data)[0]
|
||||||
new_chunk.bytes_read+=2
|
new_chunk.bytes_read+=2
|
||||||
|
|
||||||
# print 'number of verts: ', num_verts
|
# print 'number of verts: ', num_verts
|
||||||
def getvert():
|
def getvert():
|
||||||
temp_data= unpack('<3f', file.read(STRUCT_SIZE_3FLOAT))
|
temp_data= unpack('<3f', file.read(STRUCT_SIZE_3FLOAT))
|
||||||
|
|
||||||
# Set the bounds if user selected
|
|
||||||
if BOUNDS_3DS:
|
|
||||||
# xmin, ymin,zmin, xmax,ymax, zmax
|
|
||||||
if temp_data[0] < BOUNDS_3DS[0]: BOUNDS_3DS[0]= temp_data[0]
|
|
||||||
if temp_data[1] < BOUNDS_3DS[1]: BOUNDS_3DS[1]= temp_data[1]
|
|
||||||
if temp_data[2] < BOUNDS_3DS[2]: BOUNDS_3DS[2]= temp_data[2]
|
|
||||||
|
|
||||||
if temp_data[0] > BOUNDS_3DS[3]: BOUNDS_3DS[3]= temp_data[0]
|
|
||||||
if temp_data[1] > BOUNDS_3DS[4]: BOUNDS_3DS[4]= temp_data[1]
|
|
||||||
if temp_data[2] > BOUNDS_3DS[5]: BOUNDS_3DS[5]= temp_data[2]
|
|
||||||
|
|
||||||
|
|
||||||
new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each
|
new_chunk.bytes_read += STRUCT_SIZE_3FLOAT #12: 3 floats x 4 bytes each
|
||||||
return temp_data
|
return temp_data
|
||||||
|
|
||||||
@ -652,7 +626,7 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
elif (new_chunk.ID==OBJECT_FACES):
|
elif (new_chunk.ID==OBJECT_FACES):
|
||||||
# print 'elif (new_chunk.ID==OBJECT_FACES):'
|
# print 'elif (new_chunk.ID==OBJECT_FACES):'
|
||||||
temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
||||||
num_faces,= unpack('<H', temp_data)
|
num_faces= unpack('<H', temp_data)[0]
|
||||||
new_chunk.bytes_read+= 2
|
new_chunk.bytes_read+= 2
|
||||||
#print 'number of faces: ', num_faces
|
#print 'number of faces: ', num_faces
|
||||||
|
|
||||||
@ -661,9 +635,6 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
temp_data= file.read(STRUCT_SIZE_4UNSIGNED_SHORT)
|
temp_data= file.read(STRUCT_SIZE_4UNSIGNED_SHORT)
|
||||||
new_chunk.bytes_read+= STRUCT_SIZE_4UNSIGNED_SHORT #4 short ints x 2 bytes each
|
new_chunk.bytes_read+= STRUCT_SIZE_4UNSIGNED_SHORT #4 short ints x 2 bytes each
|
||||||
v1,v2,v3,dummy= unpack('<4H', temp_data)
|
v1,v2,v3,dummy= unpack('<4H', temp_data)
|
||||||
##if v1==v2 or v1==v3 or v2==v3:
|
|
||||||
## return None
|
|
||||||
# DUMMYVERT! - remove +1 when blenders internals are fixed,
|
|
||||||
return v1, v2, v3
|
return v1, v2, v3
|
||||||
|
|
||||||
contextMesh_facels= [ getface() for i in xrange(num_faces) ]
|
contextMesh_facels= [ getface() for i in xrange(num_faces) ]
|
||||||
@ -674,35 +645,22 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
material_name= read_string(file)
|
material_name= read_string(file)
|
||||||
new_chunk.bytes_read += len(material_name)+1 # remove 1 null character.
|
new_chunk.bytes_read += len(material_name)+1 # remove 1 null character.
|
||||||
|
|
||||||
tempMatFaceIndexList = contextMeshMaterials[material_name]= set()
|
|
||||||
|
|
||||||
temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
||||||
num_faces_using_mat,= unpack('<H', temp_data)
|
num_faces_using_mat = unpack('<H', temp_data)[0]
|
||||||
new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
|
new_chunk.bytes_read += STRUCT_SIZE_UNSIGNED_SHORT
|
||||||
|
|
||||||
#list of faces using mat
|
def getmat():
|
||||||
for face_counter in xrange(num_faces_using_mat):
|
|
||||||
temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
temp_data= file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
||||||
new_chunk.bytes_read+= STRUCT_SIZE_UNSIGNED_SHORT
|
new_chunk.bytes_read+= STRUCT_SIZE_UNSIGNED_SHORT
|
||||||
faceIndex,= unpack('<H', temp_data)
|
return unpack('<H', temp_data)[0]
|
||||||
|
|
||||||
# We dont have to use context face mapping.
|
contextMeshMaterials[material_name]= [ getmat() for i in xrange(num_faces_using_mat) ]
|
||||||
#if contextFaceMapping:
|
|
||||||
# meshFaceIndex= contextFaceMapping[faceIndex]
|
|
||||||
#else:
|
|
||||||
meshFaceIndex= faceIndex
|
|
||||||
|
|
||||||
if meshFaceIndex != None:
|
|
||||||
tempMatFaceIndexList.add(meshFaceIndex)
|
|
||||||
|
|
||||||
####tempMatFaceIndexList.sort()
|
|
||||||
del tempMatFaceIndexList
|
|
||||||
#look up the material in all the materials
|
#look up the material in all the materials
|
||||||
|
|
||||||
elif (new_chunk.ID==OBJECT_UV):
|
elif (new_chunk.ID==OBJECT_UV):
|
||||||
# print 'elif (new_chunk.ID==OBJECT_UV):'
|
|
||||||
temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
temp_data=file.read(STRUCT_SIZE_UNSIGNED_SHORT)
|
||||||
num_uv,=unpack('<H', temp_data)
|
num_uv=unpack('<H', temp_data)[0]
|
||||||
new_chunk.bytes_read+= 2
|
new_chunk.bytes_read+= 2
|
||||||
|
|
||||||
def getuv():
|
def getuv():
|
||||||
@ -713,19 +671,18 @@ def process_next_chunk(file, previous_chunk, importedObjects):
|
|||||||
contextMeshUV= [ getuv() for i in xrange(num_uv) ]
|
contextMeshUV= [ getuv() for i in xrange(num_uv) ]
|
||||||
|
|
||||||
elif (new_chunk.ID== OBJECT_TRANS_MATRIX):
|
elif (new_chunk.ID== OBJECT_TRANS_MATRIX):
|
||||||
# print 'elif (new_chunk.ID== OBJECT_TRANS_MATRIX):'
|
|
||||||
temp_data=file.read(STRUCT_SIZE_4x3MAT)
|
temp_data=file.read(STRUCT_SIZE_4x3MAT)
|
||||||
data= list( unpack('<ffffffffffff', temp_data) )
|
data= list( unpack('<ffffffffffff', temp_data) )
|
||||||
new_chunk.bytes_read += STRUCT_SIZE_4x3MAT
|
new_chunk.bytes_read += STRUCT_SIZE_4x3MAT
|
||||||
|
|
||||||
contextMatrix= Blender.Mathutils.Matrix(\
|
"""contextMatrix= Blender.Mathutils.Matrix(\
|
||||||
data[:3] + [0],\
|
data[:3] + [0],\
|
||||||
data[3:6] + [0],\
|
data[3:6] + [0],\
|
||||||
data[6:9] + [0],\
|
data[6:9] + [0],\
|
||||||
data[9:] + [1])
|
data[9:] + [1])
|
||||||
|
"""
|
||||||
|
|
||||||
elif (new_chunk.ID==MAT_MAP_FILENAME):
|
elif (new_chunk.ID==MAT_MAP_FILENAME):
|
||||||
raise 'Hello--'
|
|
||||||
texture_name=read_string(file)
|
texture_name=read_string(file)
|
||||||
try:
|
try:
|
||||||
TEXTURE_DICT[contextMaterial.name]
|
TEXTURE_DICT[contextMaterial.name]
|
||||||
@ -835,9 +792,21 @@ def load_3ds(filename, PREF_UI= True):
|
|||||||
ob.sel= 1
|
ob.sel= 1
|
||||||
|
|
||||||
if IMPORT_CONSTRAIN_BOUNDS!=0.0:
|
if IMPORT_CONSTRAIN_BOUNDS!=0.0:
|
||||||
|
# Set bounds from objecyt bounding box
|
||||||
|
for ob in importedObjects:
|
||||||
|
if ob.type=='Mesh':
|
||||||
|
ob.makeDisplayList() # Why dosnt this update the bounds?
|
||||||
|
for v in ob.getBoundBox():
|
||||||
|
for i in (0,1,2):
|
||||||
|
if v[i] < BOUNDS_3DS[i]:
|
||||||
|
BOUNDS_3DS[i]= v[i] # min
|
||||||
|
|
||||||
|
if v[i] > BOUNDS_3DS[i+3]:
|
||||||
|
BOUNDS_3DS[i+3]= v[i] # min
|
||||||
|
|
||||||
# Get the max axis x/y/z
|
# Get the max axis x/y/z
|
||||||
max_axis= max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2])
|
max_axis= max(BOUNDS_3DS[3]-BOUNDS_3DS[0], BOUNDS_3DS[4]-BOUNDS_3DS[1], BOUNDS_3DS[5]-BOUNDS_3DS[2])
|
||||||
|
print max_axis
|
||||||
if max_axis < 1<<30: # Should never be false but just make sure.
|
if max_axis < 1<<30: # Should never be false but just make sure.
|
||||||
|
|
||||||
# Get a new scale factor if set as an option
|
# Get a new scale factor if set as an option
|
||||||
@ -882,7 +851,7 @@ else:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
for i, _3ds in enumerate(lines):
|
for i, _3ds in enumerate(lines):
|
||||||
if between(i, 1, 40):
|
if between(i, 1,200):
|
||||||
_3ds= _3ds[:-1]
|
_3ds= _3ds[:-1]
|
||||||
print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines)
|
print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines)
|
||||||
_3ds_file= _3ds.split('/')[-1].split('\\')[-1]
|
_3ds_file= _3ds.split('/')[-1].split('\\')[-1]
|
||||||
|
Loading…
Reference in New Issue
Block a user