Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWillian Padovani Germano <wpgermano@gmail.com>2004-08-04 10:16:46 +0400
committerWillian Padovani Germano <wpgermano@gmail.com>2004-08-04 10:16:46 +0400
commit452c8cf838f5616ee750b4e512ceac6809a9a559 (patch)
treef806236705445938335b6dbdd6eecf52b6a49a04 /release/scripts/obj_import.py
parent54e1f40024e0525549e6a6bdca432f1c156ae5f9 (diff)
Done.
Scripts: - Jean-Michel Soler probably lost some hours of sleep since Sunday, but he managed to send me the updated path import scripts a few hours ago. My tests with Inkscape .svg and .ps and Gimp worked fine. He also tested a lot and sent me info about what is already supported. I'll send Ton a doc about bundled scripts including this info. Importers: .ai, .svg, .eps/.ps, Gimp 1-1.2.5 / 2.0. - Jean-Michel also contributed his Texture Baker script. - Campbell Barton contributed two new scripts: a mesh cleaner and a vloop skinning / lofting script. He also sent updates to his obj import / export ones. - A Vanpoucke (xand) contributed his Axis Orientation Copy script. And that makes 8 last minute additions. Thanks a lot to the authors and special thanks to JMS and Campbell for their hard work : ). BPython: - tiny addition (I'm forced to call it a showstopper bug ;) so JMS's path import scripts (that actually convert to obj and make Blender load the .obj curves) can use Blender.Load() and not rename G.sce, the default filename. Blender.Load(filename, 1) doesn't update G.sce. Nothing should break because of this, Load(filename) still works fine. - Made Blender complain again if script is for a newer Blender version than the one running it.
Diffstat (limited to 'release/scripts/obj_import.py')
-rw-r--r--release/scripts/obj_import.py570
1 files changed, 304 insertions, 266 deletions
diff --git a/release/scripts/obj_import.py b/release/scripts/obj_import.py
index e19c52b7be1..236b9705d33 100644
--- a/release/scripts/obj_import.py
+++ b/release/scripts/obj_import.py
@@ -53,19 +53,18 @@ def pathName(path,name):
# Strips the slashes from the back of a string #
#==============================================#
def stripPath(path):
- for CH in range(len(path), 0, -1):
- if path[CH-1] == "/" or path[CH-1] == "\\":
- path = path[CH:]
- break
- return path
+ for CH in range(len(path), 0, -1):
+ if path[CH-1] == "/" or path[CH-1] == "\\":
+ path = path[CH:]
+ break
+ return path
#====================================================#
# Strips the prefix off the name before writing #
-
#====================================================#
def stripName(name): # name is a string
- prefixDelimiter = '.'
- return name[ : name.find(prefixDelimiter) ]
+ prefixDelimiter = '.'
+ return name[ : name.find(prefixDelimiter) ]
from Blender import *
@@ -74,27 +73,27 @@ from Blender import *
# This gets a mat or creates one of the requested name if none exist. #
#==================================================================================#
def getMat(matName):
- # Make a new mat
- try:
- return Material.Get(matName)
- except:
- return Material.New(matName)
+ # Make a new mat
+ try:
+ return Material.Get(matName)
+ except:
+ return Material.New(matName)
#==================================================================================#
# This function sets textures defined in .mtl file #
#==================================================================================#
def getImg(img_fileName):
- for i in Image.Get():
- if i.filename == img_fileName:
- return i
+ for i in Image.Get():
+ if i.filename == img_fileName:
+ return i
- # if we are this far it means the image hasnt been loaded.
- try:
- return Image.Load(img_fileName)
- except:
- print "unable to open", img_fileName
- return
+ # if we are this far it means the image hasnt been loaded.
+ try:
+ return Image.Load(img_fileName)
+ except:
+ print "unable to open", img_fileName
+ return
@@ -102,270 +101,309 @@ def getImg(img_fileName):
# This function sets textures defined in .mtl file #
#==================================================================================#
def load_mat_image(mat, img_fileName, type, mesh):
- try:
- image = Image.Load(img_fileName)
- except:
- print "unable to open", img_fileName
- return
+ try:
+ image = Image.Load(img_fileName)
+ except:
+ print "unable to open", img_fileName
+ return
- texture = Texture.New(type)
- texture.setType('Image')
- texture.image = image
+ texture = Texture.New(type)
+ texture.setType('Image')
+ texture.image = image
- # adds textures to faces (Textured/Alt-Z mode)
- # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
- if type == 'Kd':
- for f in mesh.faces:
- if mesh.materials[f.mat].name == mat.name:
-
- # the inline usemat command overides the material Image
- if not f.image:
- f.image = image
+ # adds textures to faces (Textured/Alt-Z mode)
+ # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
+ if type == 'Kd':
+ for f in mesh.faces:
+ if mesh.materials[f.mat].name == mat.name:
+
+ # the inline usemat command overides the material Image
+ if not f.image:
+ f.image = image
- # adds textures for materials (rendering)
- if type == 'Ka':
- mat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.CMIR)
- if type == 'Kd':
- mat.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.COL)
- if type == 'Ks':
- mat.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
+ # adds textures for materials (rendering)
+ if type == 'Ka':
+ mat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.CMIR)
+ if type == 'Kd':
+ mat.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.COL)
+ if type == 'Ks':
+ mat.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
#==================================================================================#
# This function loads materials from .mtl file (have to be defined in obj file) #
#==================================================================================#
def load_mtl(dir, mtl_file, mesh):
- mtl_fileName = dir + mtl_file
- try:
- fileLines= open(mtl_fileName, 'r').readlines()
- except:
- print "unable to open", mtl_fileName
- return
+ # Remove ./
+ if mtl_file[:2] == './':
+ mtl_file= mtl_file[2:]
+
+ mtl_fileName = dir + mtl_file
+ try:
+ fileLines= open(mtl_fileName, 'r').readlines()
+ except:
+ print "unable to open", mtl_fileName
+ return
- lIdx=0
- while lIdx < len(fileLines):
- l = fileLines[lIdx].split()
+ lIdx=0
+ while lIdx < len(fileLines):
+ l = fileLines[lIdx].split()
- # Detect a line that will be ignored
- if len(l) == 0:
- pass
- elif l[0] == '#' or len(l) == 0:
- pass
- elif l[0] == 'newmtl':
- currentMat = getMat(' '.join(l[1:]))
- elif l[0] == 'Ka':
- currentMat.setMirCol(eval(l[1]), eval(l[2]), eval(l[3]))
- elif l[0] == 'Kd':
- currentMat.setRGBCol(eval(l[1]), eval(l[2]), eval(l[3]))
- elif l[0] == 'Ks':
- currentMat.setSpecCol(eval(l[1]), eval(l[2]), eval(l[3]))
- elif l[0] == 'Ns':
- currentMat.setHardness( int((eval(l[1])*0.51)) )
- elif l[0] == 'd':
- currentMat.setAlpha(eval(l[1]))
- elif l[0] == 'Tr':
- currentMat.setAlpha(eval(l[1]))
- elif l[0] == 'map_Ka':
- img_fileName = dir + l[1]
- load_mat_image(currentMat, img_fileName, 'Ka', mesh)
- elif l[0] == 'map_Ks':
- img_fileName = dir + l[1]
- load_mat_image(currentMat, img_fileName, 'Ks', mesh)
- elif l[0] == 'map_Kd':
- img_fileName = dir + l[1]
- load_mat_image(currentMat, img_fileName, 'Kd', mesh)
- lIdx+=1
+ # Detect a line that will be ignored
+ if len(l) == 0:
+ pass
+ elif l[0] == '#' or len(l) == 0:
+ pass
+ elif l[0] == 'newmtl':
+ currentMat = getMat(' '.join(l[1:]))
+ elif l[0] == 'Ka':
+ currentMat.setMirCol(eval(l[1]), eval(l[2]), eval(l[3]))
+ elif l[0] == 'Kd':
+ currentMat.setRGBCol(eval(l[1]), eval(l[2]), eval(l[3]))
+ elif l[0] == 'Ks':
+ currentMat.setSpecCol(eval(l[1]), eval(l[2]), eval(l[3]))
+ elif l[0] == 'Ns':
+ currentMat.setHardness( int((eval(l[1])*0.51)) )
+ elif l[0] == 'd':
+ currentMat.setAlpha(eval(l[1]))
+ elif l[0] == 'Tr':
+ currentMat.setAlpha(eval(l[1]))
+ elif l[0] == 'map_Ka':
+ img_fileName = dir + l[1]
+ load_mat_image(currentMat, img_fileName, 'Ka', mesh)
+ elif l[0] == 'map_Ks':
+ img_fileName = dir + l[1]
+ load_mat_image(currentMat, img_fileName, 'Ks', mesh)
+ elif l[0] == 'map_Kd':
+ img_fileName = dir + l[1]
+ load_mat_image(currentMat, img_fileName, 'Kd', mesh)
+ lIdx+=1
#==================================================================================#
# This loads data from .obj file #
#==================================================================================#
def load_obj(file):
- def applyMat(mesh, f, mat):
- # Check weather the 16 mat limit has been met.
- if len( mesh.materials ) >= MATLIMIT:
- print 'Warning, max material limit reached, using an existing material'
- return mesh, f
-
- mIdx = 0
- for m in mesh.materials:
- if m.getName() == mat.getName():
- break
- mIdx+=1
-
- if mIdx == len(mesh.materials):
- mesh.addMaterial(mat)
-
- f.mat = mIdx
+ def applyMat(mesh, f, mat):
+ # Check weather the 16 mat limit has been met.
+ if len( mesh.materials ) >= MATLIMIT:
+ print 'Warning, max material limit reached, using an existing material'
return mesh, f
-
- # Get the file name with no path or .obj
- fileName = stripName( stripPath(file) )
-
- mtl_fileName = ''
-
- DIR = pathName(file, stripPath(file))
-
- fileLines = open(file, 'r').readlines()
-
- mesh = NMesh.GetRaw() # new empty mesh
-
- objectName = 'mesh' # If we cant get one, use this
-
- uvMapList = [] # store tuple uv pairs here
-
- nullMat = getMat(NULL_MAT)
-
- currentMat = nullMat # Use this mat.
- currentImg = NULL_IMG # Null image is a string, otherwise this should be set to an image object.
+
+ mIdx = 0
+ for m in mesh.materials:
+ if m.getName() == mat.getName():
+ break
+ mIdx+=1
+
+ if mIdx == len(mesh.materials):
+ mesh.addMaterial(mat)
+
+ f.mat = mIdx
+ return mesh, f
+
+ # Get the file name with no path or .obj
+ fileName = stripName( stripPath(file) )
+
+ mtl_fileName = ''
+
+ DIR = pathName(file, stripPath(file))
- smooth = 0
+ fileLines = open(file, 'r').readlines()
+
+ mesh = NMesh.GetRaw() # new empty mesh
+
+ objectName = 'mesh' # If we cant get one, use this
+
+ uvMapList = [(0,0)] # store tuple uv pairs here
+
+ # This dummy vert makes life a whole lot easier-
+ # pythons index system then aligns with objs, remove later
+ vertList = [NMesh.Vert(0, 0, 0)] # store tuple uv pairs here
+
+ # Here we store a boolean list of which verts are used or not
+ # no we know weather to add them to the current mesh
+ # This is an issue with global vertex indicies being translated to per mesh indicies
+ # like blenders, we start with a dummy just like the vert.
+ # -1 means unused, any other value refers to the local mesh index of the vert.
+ usedList = [-1]
+
+ nullMat = getMat(NULL_MAT)
+
+ currentMat = nullMat # Use this mat.
+ currentImg = NULL_IMG # Null image is a string, otherwise this should be set to an image object.
- # Main loop
- lIdx = 0
- while lIdx < len(fileLines):
- l = fileLines[lIdx].split()
-
- # Detect a line that will be idnored
- if len(l) == 0:
- pass
- elif l[0] == '#' or len(l) == 0:
- pass
- # VERTEX
- elif l[0] == 'v':
- # This is a new vert, make a new mesh
- mesh.verts.append( NMesh.Vert(eval(l[1]), eval(l[2]), eval(l[3]) ) )
-
- elif l[0] == 'vn':
- pass
-
- elif l[0] == 'vt':
- # This is a new vert, make a new mesh
- uvMapList.append( (eval(l[1]), eval(l[2])) )
-
- elif l[0] == 'f':
-
- # Make a face with the correct material.
- f = NMesh.Face()
- mesh, f = applyMat(mesh, f, currentMat)
-
- # Set up vIdxLs : Verts
- # Set up vtIdxLs : UV
- vIdxLs = []
- vtIdxLs = []
- for v in l[1:]:
- # OBJ files can have // or / to seperate vert/texVert/normal
- # this is a bit of a pain but we must deal with it.
- # Well try // first and if that has a len of 1 then we'll try /
- objVert = v.split('//', -1)
- if len(objVert) == 1:
- objVert = objVert[0].split('/', -1)
-
- # VERT INDEX
- vIdxLs.append(eval(objVert[0]) -1)
- # UV
- if len(objVert) == 1:
- vtIdxLs.append(eval(objVert[0]) -1) # Sticky UV coords
- else:
- vtIdxLs.append(eval(objVert[1]) -1) # Seperate UV coords
-
- # Quads only, we could import quads using the method below but it polite to import a quad as a quad.f
- if len(vIdxLs) == 4:
- f.v.append(mesh.verts[vIdxLs[0]])
- f.v.append(mesh.verts[vIdxLs[1]])
- f.v.append(mesh.verts[vIdxLs[2]])
- f.v.append(mesh.verts[vIdxLs[3]])
- # SMOTH FACE
- f.smooth = smooth
- # UV MAPPING
- if uvMapList:
- if vtIdxLs[0] < len(uvMapList):
- f.uv.append( uvMapList[ vtIdxLs[0] ] )
- if vtIdxLs[1] < len(uvMapList):
- f.uv.append( uvMapList[ vtIdxLs[1] ] )
- if vtIdxLs[2] < len(uvMapList):
- f.uv.append( uvMapList[ vtIdxLs[2] ] )
- if vtIdxLs[3] < len(uvMapList):
- f.uv.append( uvMapList[ vtIdxLs[3] ] )
-
- mesh.faces.append(f) # move the face onto the mesh
- # Apply the current image to the face
- if currentImg != NULL_IMG:
- mesh.faces[-1].image = currentImg
+ # Main loop
+ lIdx = 0
+ while lIdx < len(fileLines):
+ l = fileLines[lIdx].split()
+
+ # Detect a line that will be idnored
+ if len(l) == 0:
+ pass
+ elif l[0] == '#' or len(l) == 0:
+ pass
+ # VERTEX
+ elif l[0] == 'v':
+ # This is a new vert, make a new mesh
+ vertList.append( NMesh.Vert(eval(l[1]), eval(l[2]), eval(l[3]) ) )
+ usedList.append(-1) # Ad the moment this vert is not used by any mesh.
+
+ elif l[0] == 'vn':
+ pass
+
+ elif l[0] == 'vt':
+ # This is a new vert, make a new mesh
+ uvMapList.append( (eval(l[1]), eval(l[2])) )
- elif len(vIdxLs) >= 3: # This handles tri's and fans
- for i in range(len(vIdxLs)-2):
- f = NMesh.Face()
- mesh, f = applyMat(mesh, f, currentMat)
- f.v.append(mesh.verts[vIdxLs[0]])
- f.v.append(mesh.verts[vIdxLs[i+1]])
- f.v.append(mesh.verts[vIdxLs[i+2]])
- # SMOTH FACE
- f.smooth = smooth
- # UV MAPPING
- if uvMapList:
- if vtIdxLs[0] < len(uvMapList):
- f.uv.append( uvMapList[ vtIdxLs[0] ] )
- if vtIdxLs[1] < len(uvMapList):
- f.uv.append( uvMapList[ vtIdxLs[i+1] ] )
- if vtIdxLs[2] < len(uvMapList):
- f.uv.append( uvMapList[ vtIdxLs[i+2] ] )
-
- mesh.faces.append(f) # move the face onto the mesh
- # Apply the current image to the face
- if currentImg != NULL_IMG:
- mesh.faces[-1].image = currentImg
-
-
- # is o the only vert/face delimeter?
- # if not we could be screwed.
- elif l[0] == 'o':
- # Some material stuff
- if mtl_fileName != '':
- load_mtl(DIR, mtl_fileName, mesh)
+ elif l[0] == 'f':
+
+ # Make a face with the correct material.
+ f = NMesh.Face()
+ mesh, f = applyMat(mesh, f, currentMat)
+
+ # Set up vIdxLs : Verts
+ # Set up vtIdxLs : UV
+ # Start with a dummy objects so python accepts OBJs 1 is the first index.
+ vIdxLs = []
+ vtIdxLs = []
+ fHasUV = len(uvMapList)-1 # Assume the face has a UV until it sho it dosent, if there are no UV coords then this will start as 0.
+ for v in l[1:]:
+ # OBJ files can have // or / to seperate vert/texVert/normal
+ # this is a bit of a pain but we must deal with it.
+ objVert = v.split('/', -1)
- # Make sure the objects is worth puttong
- if len(mesh.verts) > 0:
- NMesh.PutRaw(mesh, fileName + '_' + objectName)
- # Make new mesh
- mesh = NMesh.GetRaw()
-
- # New mesh name
- objectName = '_'.join(l[1:]) # Use join in case of spaces
-
- # New texture list
- uvMapList = []
-
- # setting smooth surface on or off
- elif l[0] == 's':
- if l[1] == 'off':
- smooth = 0
- else:
- smooth = 1
-
- elif l[0] == 'usemtl':
- if l[1] == '(null)':
- currentMat = getMat(NULL_MAT)
- else:
- currentMat = getMat(' '.join(l[1:])) # Use join in case of spaces
+ # Vert Index - OBJ supports negative index assignment (like python)
+
+ vIdxLs.append(eval(objVert[0]))
+ if fHasUV:
+ # UV
+ if len(objVert) == 1:
+ vtIdxLs.append(eval(objVert[0])) # Sticky UV coords
+ elif objVert[1] != '': # Its possible that theres no texture vert just he vert and normal eg 1//2
+ vtIdxLs.append(eval(objVert[1])) # Seperate UV coords
+ else:
+ fHasUV = 0
+
+ # Dont add a UV to the face if its larger then the UV coord list
+ # The OBJ file would have to be corrupt or badly written for thi to happen
+ # but account for it anyway.
+ if vtIdxLs[-1] > len(uvMapList):
+ fHasUV = 0
+ print 'badly written OBJ file, invalid references to UV Texture coordinates.'
+
+ # Quads only, we could import quads using the method below but it polite to import a quad as a quad.
+ if len(vIdxLs) == 4:
+ for i in [0,1,2,3]:
+ if usedList[vIdxLs[i]] == -1:
+ mesh.verts.append(vertList[vIdxLs[i]])
+ f.v.append(mesh.verts[-1])
+ usedList[vIdxLs[i]] = len(mesh.verts)-1
+ else:
+ f.v.append(mesh.verts[usedList[vIdxLs[i]]])
+
+ # UV MAPPING
+ if fHasUV:
+ for i in [0,1,2,3]:
+ f.uv.append( uvMapList[ vtIdxLs[i] ] )
+ mesh.faces.append(f) # move the face onto the mesh
+ # Apply the current image to the face
+ if currentImg != NULL_IMG:
+ mesh.faces[-1].image = currentImg
+
+ elif len(vIdxLs) >= 3: # This handles tri's and fans
+ for i in range(len(vIdxLs)-2):
+ f = NMesh.Face()
+ mesh, f = applyMat(mesh, f, currentMat)
+
+ if usedList[vIdxLs[0]] == -1:
+ mesh.verts.append(vertList[vIdxLs[0]])
+ f.v.append(mesh.verts[-1])
+ usedList[vIdxLs[0]] = len(mesh.verts)-1
+ else:
+ f.v.append(mesh.verts[usedList[vIdxLs[0]]])
+
+ if usedList[vIdxLs[i+1]] == -1:
+ mesh.verts.append(vertList[vIdxLs[i+1]])
+ f.v.append(mesh.verts[-1])
+ usedList[vIdxLs[i+1]] = len(mesh.verts)-1
+ else:
+ f.v.append(mesh.verts[usedList[vIdxLs[i+1]]])
+
+ if usedList[vIdxLs[i+2]] == -1:
+ mesh.verts.append(vertList[vIdxLs[i+2]])
+ f.v.append(mesh.verts[-1])
+ usedList[vIdxLs[i+2]] = len(mesh.verts)-1
+ else:
+ f.v.append(mesh.verts[usedList[vIdxLs[i+2]]])
+
+ # UV MAPPING
+ if fHasUV:
+ f.uv.append( uvMapList[ vtIdxLs[0] ] )
+ f.uv.append( uvMapList[ vtIdxLs[i+1] ] )
+ f.uv.append( uvMapList[ vtIdxLs[i+2] ] )
+ mesh.faces.append(f) # move the face onto the mesh
+
+ # Apply the current image to the face
+ if currentImg != NULL_IMG:
+ mesh.faces[-1].image = currentImg
+
+ # Object / Group
+ elif l[0] == 'o' or l[0] == 'g':
+
+ # Reset the used list
+ ulIdx = 0
+ while ulIdx < len(usedList):
+ usedList[ulIdx] = -1
+ ulIdx +=1
+
+ # Some material stuff
+ if mtl_fileName != '':
+ load_mtl(DIR, mtl_fileName, mesh)
+
+ # Make sure the objects is worth putting
+ if len(mesh.verts) > 1:
+ mesh.verts.remove(mesh.verts[0])
+ ob = NMesh.PutRaw(mesh, fileName + '_' + objectName)
+ if ob != None: # Name the object too.
+ ob.name = fileName + '_' + objectName
- elif l[0] == 'usemat':
- if l[1] == '(null)':
- currentImg = NULL_IMG
- else:
- currentImg = getImg(DIR + ' '.join(l[1:])) # Use join in case of spaces
-
-
- elif l[0] == 'mtllib':
- mtl_fileName = l[1]
-
- lIdx+=1
+ # Make new mesh
+ mesh = NMesh.GetRaw()
+ # This dummy vert makes life a whole lot easier-
+ # pythons index system then aligns with objs, remove later
+ mesh.verts.append( NMesh.Vert(0, 0, 0) )
+
+ # New mesh name
+ objectName = '_'.join(l[1:]) # Use join in case of spaces
+
+
+ elif l[0] == 'usemtl':
+ if l[1] == '(null)':
+ currentMat = getMat(NULL_MAT)
+ else:
+ currentMat = getMat(' '.join(l[1:])) # Use join in case of spaces
+
+ elif l[0] == 'usemat':
+ if l[1] == '(null)':
+ currentImg = NULL_IMG
+ else:
+ currentImg = getImg(DIR + ' '.join(l[1:])) # Use join in case of spaces
+
+
+ elif l[0] == 'mtllib':
+ mtl_fileName = l[1]
+
+ lIdx+=1
- # Some material stuff
- if mtl_fileName != '':
- load_mtl(DIR, mtl_fileName, mesh)
-
- # We need to do this to put the last object.
- # All other objects will be put alredy
- if len(mesh.verts) > 0:
- NMesh.PutRaw(mesh, fileName + '_' + objectName)
+ # Some material stuff
+ if mtl_fileName != '':
+ load_mtl(DIR, mtl_fileName, mesh)
+
+ # We need to do this to put the last object.
+ # All other objects will be put alredy
+ if len(mesh.verts) > 1:
+ mesh.verts.remove(mesh.verts[0])
+ ob = NMesh.PutRaw(mesh, fileName + '_' + objectName)
+ if ob != None: # Name the object too.
+ ob.name = fileName + '_' + objectName
-Window.FileSelector(load_obj, 'Import OBJ')
+Window.FileSelector(load_obj, 'Import Wavefront OBJ')