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:
authorJiri Hnidek <jiri.hnidek@tul.cz>2004-06-15 00:51:09 +0400
committerJiri Hnidek <jiri.hnidek@tul.cz>2004-06-15 00:51:09 +0400
commit317e067ecb91c2127c12cee3808a5bb2402b82e4 (patch)
tree6a487191cad5b1d45fe494ca2b5023e1dec69f1b /release
parentf24be4c6ade18276a1210afac44c66b9329afe20 (diff)
- 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.
Diffstat (limited to 'release')
-rw-r--r--release/scripts/obj_import.py418
1 files changed, 247 insertions, 171 deletions
diff --git a/release/scripts/obj_import.py b/release/scripts/obj_import.py
index 412a5d285a9..41daba823f8 100644
--- a/release/scripts/obj_import.py
+++ b/release/scripts/obj_import.py
@@ -1,176 +1,245 @@
-#!BPY
-
-"""
-Name: 'Wavefront (.obj)...'
-Blender: 232
-Group: 'Import'
-Tooltip: 'Load a Wavefront OBJ File'
- """
+#!BPY
+
+"""
+Name: 'Wavefront (.obj)...'
+Blender: 232
+Group: 'Import'
+Tooltip: 'Load a Wavefront OBJ File'
+"""
# $Id$
#
-# --------------------------------------------------------------------------
-# OBJ Import v0.9 by Campbell Barton (AKA Ideasman)
-# --------------------------------------------------------------------------
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** 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
-
-#==============================================#
-# 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
-
-#====================================================#
-# 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 #
-#===============================#
-def join(joinList):
- joinedString = ""
- for listItem in joinList:
- joinedString = joinedString + ' ' + str(listItem)
-
- # Remove the first space
- joinedString = joinedString[1:]
- return joinedString
-
-
-from Blender import *
-
-def load_obj(file):
- # 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)
-
- 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
+# --------------------------------------------------------------------------
+# OBJ Import v0.9 by Campbell Barton (AKA Ideasman)
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+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 #
+#==============================================#
+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
+
+#====================================================#
+# Strips the prefix off the name before writing #
+
+#====================================================#
+def stripName(name): # name is a string
+ prefixDelimiter = '.'
+ return name[ : name.find(prefixDelimiter) ]
+
+#===============================#
+# Join list items into a string #
+#===============================#
+def join(joinList):
+ joinedString = ""
+ for listItem in joinList:
+ joinedString = joinedString + ' ' + str(listItem)
+
+ # Remove the first space
+ joinedString = joinedString[1:]
+ return joinedString
+
+
+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)
+
+#==================================================================================#
+# 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:
+ 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
+ mIdx = 0
+ for m in mesh.materials:
+ if m.getName() == mat.getName():
+ break
+ mIdx+=1
- if mIdx == len(mesh.materials):
- mesh.addMaterial(mat)
+ 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) )
-
- 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.
-
- # Main loop
- lIdx = 0
- while lIdx < len(fileLines):
- l = split(fileLines[lIdx], WHITESPACE)
+ 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))
+
+ 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.
+
+ # 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]) ) )
-
+ # 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
+
+ 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:]:
- objVert = split( v, ['/'] )
+ for v in l[1:]:
+ #objVert = split( v, ['/'] )
+ objVert = v.split('/', -1)
# VERT INDEX
vIdxLs.append(eval(objVert[0]) -1)
@@ -179,8 +248,8 @@ def load_obj(file):
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
+
+ # 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]])
@@ -213,7 +282,7 @@ def load_obj(file):
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
# is o the only vert/face delimeter?
@@ -224,11 +293,11 @@ def load_obj(file):
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
+
+ # New texture list
uvMapList = []
elif l[0] == 'usemtl':
@@ -236,12 +305,19 @@ def load_obj(file):
currentMat = getMat(NULL_MAT)
else:
currentMat = getMat(join(l[1:])) # Use join in case of spaces
+
+ elif l[0] == 'mtllib':
+ mtl_fileName = l[1]
- lIdx+=1
+ lIdx+=1
- # 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) > 0:
+ NMesh.PutRaw(mesh, fileName + '_' + objectName)
-Window.FileSelector(load_obj, 'Import OBJ')
+Window.FileSelector(load_obj, 'Import OBJ')