forked from bartvdbraak/blender
- Campbell Barton's (AKA Ideasman) obj importer script (some split improvements)
- I added support of material and texture import (.mtl files) Textures are assigned to faces and materials too.
This commit is contained in:
parent
f24be4c6ad
commit
317e067ecb
@ -31,11 +31,23 @@ Tooltip: 'Load a Wavefront OBJ File'
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
WHITESPACE = [' ', '\n', '\r', '\t', '\f', '\v'] # used for the split function.
|
||||
NULL_MAT = '(null)' # Name for mesh's that have no mat set.
|
||||
|
||||
MATLIMIT = 16
|
||||
|
||||
DIR = ''
|
||||
|
||||
#==============================================#
|
||||
# Return directory, where is file #
|
||||
#==============================================#
|
||||
def pathName(path,name):
|
||||
length=len(path)
|
||||
for CH in range(1, length):
|
||||
if path[length-CH:] == name:
|
||||
path = path[:length-CH]
|
||||
break
|
||||
return path
|
||||
|
||||
#==============================================#
|
||||
# Strips the slashes from the back of a string #
|
||||
#==============================================#
|
||||
@ -48,38 +60,12 @@ def stripPath(path):
|
||||
|
||||
#====================================================#
|
||||
# Strips the prefix off the name before writing #
|
||||
|
||||
#====================================================#
|
||||
def stripName(name): # name is a string
|
||||
prefixDelimiter = '.'
|
||||
return name[ : name.find(prefixDelimiter) ]
|
||||
|
||||
#================================================================#
|
||||
# Replace module deps 'string' for join and split # #
|
||||
# - Split splits a string into a list, and join does the reverse #
|
||||
#================================================================#
|
||||
def split(splitString, WHITESPACE):
|
||||
splitList = []
|
||||
charIndex = 0
|
||||
while charIndex < len(splitString):
|
||||
# Skip white space
|
||||
while charIndex < len(splitString):
|
||||
if splitString[charIndex] in WHITESPACE:
|
||||
charIndex += 1
|
||||
else:
|
||||
break
|
||||
|
||||
# Gather text that is not white space and append to splitList
|
||||
startWordCharIndex = charIndex
|
||||
while charIndex < len(splitString):
|
||||
if splitString[charIndex] in WHITESPACE: break
|
||||
charIndex += 1
|
||||
|
||||
# Now we have the first and last chars we can append the word to the list
|
||||
if charIndex != startWordCharIndex:
|
||||
splitList.append(splitString[startWordCharIndex:charIndex])
|
||||
|
||||
return splitList
|
||||
|
||||
#===============================#
|
||||
# Join list items into a string #
|
||||
#===============================#
|
||||
@ -95,8 +81,9 @@ def join(joinList):
|
||||
|
||||
from Blender import *
|
||||
|
||||
def load_obj(file):
|
||||
# This gets a mat or creates one of the requested name if none exist.
|
||||
#==================================================================================#
|
||||
# This gets a mat or creates one of the requested name if none exist. #
|
||||
#==================================================================================#
|
||||
def getMat(matName):
|
||||
# Make a new mat
|
||||
try:
|
||||
@ -104,6 +91,83 @@ def load_obj(file):
|
||||
except:
|
||||
return Material.New(matName)
|
||||
|
||||
#==================================================================================#
|
||||
# This function sets textures defined in .mtl file #
|
||||
#==================================================================================#
|
||||
def load_image(mat, img_fileName, type, mesh):
|
||||
try:
|
||||
image = Image.Load(img_fileName)
|
||||
except:
|
||||
print "unable to open", img_fileName
|
||||
return
|
||||
|
||||
texture = Texture.New(type)
|
||||
texture.setType('Image')
|
||||
texture.image = image
|
||||
|
||||
# adds textures to faces (Textured/Alt-Z mode)
|
||||
for f in mesh.faces:
|
||||
if mesh.materials[f.mat].name == mat.name:
|
||||
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)
|
||||
|
||||
#==================================================================================#
|
||||
# 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
|
||||
|
||||
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.setEmit(eval(l[1])/100.0)
|
||||
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_image(currentMat, img_fileName, 'Ka', mesh)
|
||||
elif l[0] == 'map_Kd':
|
||||
img_fileName = dir + l[1]
|
||||
load_image(currentMat, img_fileName, 'Kd', mesh)
|
||||
elif l[0] == 'map_Ks':
|
||||
img_fileName = dir + l[1]
|
||||
load_image(currentMat, img_fileName, 'Ks', 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:
|
||||
@ -125,6 +189,10 @@ def load_obj(file):
|
||||
# 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
|
||||
@ -140,7 +208,7 @@ def load_obj(file):
|
||||
# Main loop
|
||||
lIdx = 0
|
||||
while lIdx < len(fileLines):
|
||||
l = split(fileLines[lIdx], WHITESPACE)
|
||||
l = fileLines[lIdx].split()
|
||||
|
||||
# Detect a line that will be idnored
|
||||
if len(l) == 0:
|
||||
@ -170,7 +238,8 @@ def load_obj(file):
|
||||
vIdxLs = []
|
||||
vtIdxLs = []
|
||||
for v in l[1:]:
|
||||
objVert = split( v, ['/'] )
|
||||
#objVert = split( v, ['/'] )
|
||||
objVert = v.split('/', -1)
|
||||
|
||||
# VERT INDEX
|
||||
vIdxLs.append(eval(objVert[0]) -1)
|
||||
@ -237,8 +306,15 @@ def load_obj(file):
|
||||
else:
|
||||
currentMat = getMat(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:
|
||||
|
Loading…
Reference in New Issue
Block a user