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:
authorCampbell Barton <ideasman42@gmail.com>2006-02-04 06:44:21 +0300
committerCampbell Barton <ideasman42@gmail.com>2006-02-04 06:44:21 +0300
commitfaff1cf46b1c12401f4f2a604cc3d464abe9fc2b (patch)
treea975cb735c159b509ad11a03cea050d42a461e8b /release
parent902bc75c345c6f2765db787b4304907e77bd2a50 (diff)
Fixed bug where a extra vert was duplicated. - (Thanks Brandedo)
Face indicies spanning over 1 line are now supported (had a freak obj that did this) Small optimization @% overall speedup. - Last release before move to Mesh over NMesh.
Diffstat (limited to 'release')
-rw-r--r--release/scripts/obj_import.py337
1 files changed, 74 insertions, 263 deletions
diff --git a/release/scripts/obj_import.py b/release/scripts/obj_import.py
index f2bcaf853e7..08b4429a1f9 100644
--- a/release/scripts/obj_import.py
+++ b/release/scripts/obj_import.py
@@ -71,21 +71,7 @@ def stripExt(name): # name is a string
from Blender import *
-
-
-
-# Adds a slash to the end of a path if its not there.
-def addSlash(path):
- if path.endswith('\\') or path.endswith('/'):
- return path
- return path + sys.sep
-
-
-def getExt(name):
- index = name.rfind('.')
- if index != -1:
- return name[index+1:]
- return name
+import BPyImage
try:
import os
@@ -94,189 +80,6 @@ except:
print 'Module "os" not found, install python to enable comprehensive image finding and batch loading.'
os = None
-#===========================================================================#
-# Comprehansive image loader, will search and find the image #
-# Will return a blender image or none if the image is missing #
-#===========================================================================#
-def comprehansiveImageLoad(imagePath, filePath):
-
- # When we have the file load it with this. try/except niceness.
- def imageLoad(path):
- try:
- img = Image.Load(path)
- print '\t\tImage loaded "%s"' % path
- return img
- except:
- print '\t\tImage failed loading "%s", mabe its not a format blender can read.' % (path)
- return None
-
- # Image formats blender can read
- IMAGE_EXT = ['jpg', 'jpeg', 'png', 'tga', 'bmp', 'rgb', 'sgi', 'bw', 'iff', 'lbm', # Blender Internal
- 'gif', 'psd', 'tif', 'tiff', 'pct', 'pict', 'pntg', 'qtif'] # Quacktime, worth a try.
-
-
-
-
- print '\tAttempting to load "%s"' % imagePath
- if sys.exists(imagePath):
- print '\t\tFile found where expected.'
- return imageLoad(imagePath)
-
- imageFileName = stripPath(imagePath) # image path only
- imageFileName_lower = imageFileName.lower() # image path only
- imageFileName_noext = stripExt(imageFileName) # With no extension.
- imageFileName_noext_lower = stripExt(imageFileName_lower) # With no extension.
- imageFilePath = stripFile(imagePath)
-
- # Remove relative path from image path
- if imageFilePath.startswith('./') or imageFilePath.startswith('.\\'):
- imageFilePath = imageFilePath[2:]
-
-
- # Attempt to load from obj path.
- tmpPath = stripFile(filePath) + stripFile(imageFilePath)
- if sys.exists(tmpPath):
- print '\t\tFile found in obj dir.'
- return imageLoad(imagePath)
-
- # OS NEEDED IF WE GO ANY FURTHER.
- if not os:
- return
-
-
- # We have os.
- # GATHER PATHS.
- paths = {} # Store possible paths we may use, dict for no doubles.
- tmpPath = addSlash(sys.expandpath('//')) # Blenders path
- if sys.exists(tmpPath):
- print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
-
- tmpPath = imageFilePath
- if sys.exists(tmpPath):
- print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
-
- tmpPath = stripFile(filePath)
- if sys.exists(tmpPath):
- print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
-
- tmpPath = addSlash(Get('texturesdir'))
- if tmpPath and sys.exists(tmpPath):
- print '\t\tSearching in %s' % tmpPath
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
-
- # Add path if relative image patrh was given.
- for k in paths.iterkeys():
- tmpPath = k + imageFilePath
- if sys.exists(tmpPath):
- paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading
- paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
- paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
- # DONE
-
-
- #
- for path, files in paths.iteritems():
-
- if sys.exists(path + imageFileName):
- return imageLoad(path + imageFileName)
-
- # If the files not there then well do a case insensitive seek.
- filesOrigCase = files[0]
- filesLower = files[1]
- filesLowerNoExt = files[2]
-
- # We are going to try in index the file directly, if its not there just keep on
- index = None
- try:
- # Is it just a case mismatch?
- index = filesLower.index(imageFileName_lower)
- except:
- try:
- # Have the extensions changed?
- index = filesLowerNoExt.index(imageFileName_noext_lower)
-
- ext = getExt( filesLower[index] ) # Get the extension of the file that matches all but ext.
-
- # Check that the ext is useable eg- not a 3ds file :)
- if ext.lower() not in IMAGE_EXT:
- index = None
-
- except:
- index = None
-
- if index != None:
- tmpPath = path + filesOrigCase[index]
- img = imageLoad( tmpPath )
- if img != None:
- print '\t\tImage Found "%s"' % tmpPath
- return img
-
-
- # IMAGE NOT FOUND IN ANY OF THE DIRS!, DO A RECURSIVE SEARCH.
- print '\t\tImage Not Found in any of the dirs, doing a recusrive search'
- for path in paths.iterkeys():
- # Were not going to use files
-
-
- #------------------
- # finds the file starting at the root.
- # def findImage(findRoot, imagePath):
- #W---------------
-
- # ROOT, DIRS, FILES
- pathWalk = os.walk(path)
- pathList = [True]
-
- matchList = [] # Store a list of (match, size), choose the biggest.
- while True:
- try:
- pathList = pathWalk.next()
- except:
- break
-
- for file in pathList[2]:
- file_lower = file.lower()
- # FOUND A MATCH
- if (file_lower == imageFileName_lower) or\
- (stripExt(file_lower) == imageFileName_noext_lower and getExt(file_lower) in IMAGE_EXT):
- name = pathList[0] + sys.sep + file
- size = os.path.getsize(name)
- print '\t\t\tfound:', name
- matchList.append( (name, size) )
-
- if matchList:
- # Sort by file size
- matchList.sort(lambda A, B: cmp(B[1], A[1]) )
-
- print '\t\tFound "%s"' % matchList[0][0]
-
- # Loop through all we have found
- img = None
- for match in matchList:
- img = imageLoad(match[0]) # 0 - first, 0 - pathname
- if img != None:
- break
- return img
-
- # No go.
- print '\t\tImage Not Found "%s"' % imagePath
- return None
-
-
-
-
-
#==================================================================================#
# This function sets textures defined in .mtl file #
#==================================================================================#
@@ -292,7 +95,7 @@ def loadMaterialImage(mat, img_fileName, type, meshDict, dir):
texture.setType('Image')
# Absolute path - c:\.. etc would work here
- image = comprehansiveImageLoad(img_fileName, dir)
+ image = BPyImage.comprehansiveImageLoad(img_fileName, dir)
if image:
texture.image = image
@@ -483,9 +286,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
#==================================================================================#
# Load all verts first (texture verts too) #
#==================================================================================#
-
print '\tfile length: %d' % len(fileLines)
-
# Ignore normals and comments.
fileLines = [lsplit for l in fileLines if not l.startswith('vn') if not l.startswith('#') for lsplit in (l.split(),) if lsplit]
Vert = NMesh.Vert
@@ -496,7 +297,6 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
print '\tvert:%i texverts:%i smoothgroups:%i materials:%s' % (len(vertList), len(uvMapList), len(smoothingGroups), len(materialDict))
# Replace filelines, Excluding v excludes "v ", "vn " and "vt "
-
# Remove any variables we may have created.
try: del _dummy
except: pass
@@ -510,6 +310,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
except: pass
del Vert
+
# With negative values this is used a lot. make faster access.
len_uvMapList = len(uvMapList)
len_vertList = len(vertList)
@@ -525,7 +326,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
# Make a list of all unused vert indicies that we can copy from
- VERT_USED_LIST = [0]*len_vertList
+ VERT_USED_LIST = [-1]*len_vertList
# Here we store a boolean list of which verts are used or not
# no we know weather to add them to the current mesh
@@ -552,7 +353,6 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
currentUsedVertListSmoothGroup = VERT_USED_LIST[:]
currentUsedVertList= {currentSmoothGroup: currentUsedVertListSmoothGroup }
-
# 0:NMesh, 1:SmoothGroups[UsedVerts[0,0,0,0]], 2:materialMapping['matname':matIndexForThisNMesh]
meshDict = {currentObjectName: (currentMesh, currentUsedVertList, currentMaterialMeshMapping) }
@@ -570,12 +370,10 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
#==================================================================================#
# Load all faces into objects, main loop #
#==================================================================================#
- #lIdx = 0
- # Face and Object loading LOOP
- #while lIdx < len(fileLines):
- # l = fileLines[lIdx]
- #for lIdx
- for l in fileLines:
+ lIdx = 0
+ while lIdx < len(fileLines):
+ l = fileLines[lIdx]
+ #for l in fileLines:
if len(l) == 0:
continue
# FACE
@@ -602,47 +400,63 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
fHasUV = len_uvMapList # 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('/')
-
- # Vert Index - OBJ supports negative index assignment (like python)
- index = int(objVert[0])-1
- # Account for negative indicies.
- if index < 0:
- index = len_vertList+index+1
-
- vIdxLs.append(index)
- if fHasUV:
- # UV
- index = 0 # Dummy var
- if len(objVert) == 1:
- index = vIdxLs[-1]
- elif objVert[1]: # != '' # Its possible that theres no texture vert just he vert and normal eg 1//2
- index = int(objVert[1])-1
- if index < 0:
- index = len_uvMapList+index+1
-
- if len_uvMapList > index:
- vtIdxLs.append(index) # Seperate UV coords
- else:
- # BAD FILE, I have found this so I account for it.
- # INVALID UV COORD
- # Could ignore this- only happens with 1 in 1000 files.
- badObjFaceTexCo +=1
- vtIdxLs.append(1)
-
- 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 len(vtIdxLs) > 0:
- if vtIdxLs[-1] > len_uvMapList:
- fHasUV = 0
+
+ # Support stupid multiline faces
+ # not an obj spec but some objs exist that do this.
+ # f 1 2 3 \
+ # 4 5 6 \
+ # ..... instead of the more common and sane.
+ # f 1 2 3 4 5 6
+ #
+ # later lines are not modified, just skepped by advancing "lIdx"
+ while l[-1] == '\\':
+ l.pop()
+ lIdx+=1
+ l.extend(fileLines[lIdx])
+ # Done supporting crappy obj faces over multiple lines.
+
+ for v in l:
+ if v is not 'f': # Only the first v will be f, any better ways to skip it?
+ # 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('/')
+
+ # Vert Index - OBJ supports negative index assignment (like python)
+ index = int(objVert[0])-1
+ # Account for negative indicies.
+ if index < 0:
+ index = len_vertList+index+1
+
+ vIdxLs.append(index)
+ if fHasUV:
+ # UV
+ index = 0 # Dummy var
+ if len(objVert) == 1:
+ index = vIdxLs[-1]
+ elif objVert[1]: # != '' # Its possible that theres no texture vert just he vert and normal eg 1//2
+ index = int(objVert[1])-1
+ if index < 0:
+ index = len_uvMapList+index+1
+
+ if len_uvMapList > index:
+ vtIdxLs.append(index) # Seperate UV coords
+ else:
+ # BAD FILE, I have found this so I account for it.
+ # INVALID UV COORD
+ # Could ignore this- only happens with 1 in 1000 files.
+ badObjFaceTexCo +=1
+ vtIdxLs.append(1)
- badObjUvs +=1 # ERROR, Cont
+ 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 len(vtIdxLs) > 0:
+ if vtIdxLs[-1] > len_uvMapList:
+ fHasUV = 0
+
+ badObjUvs +=1 # ERROR, Cont
# Quads only, we could import quads using the method below but it polite to import a quad as a quad.
#print lIdx, len(vIdxLs), len(currentUsedVertListSmoothGroup)
#print fileLines[lIdx]
@@ -650,7 +464,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
if IMPORT_EDGES:
# Edge
for i in (0,1):
- if currentUsedVertListSmoothGroup[vIdxLs[i]] == 0:
+ if currentUsedVertListSmoothGroup[vIdxLs[i]] == -1:
faceQuadVList[i] = vertList[vIdxLs[i]]
currentMesh.verts.append(faceQuadVList[i])
currentUsedVertListSmoothGroup[vIdxLs[i]] = len(currentMesh.verts)-1
@@ -671,7 +485,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
badObjFaceVerts+=1
else:
for i in quadList: # quadList == [0,1,2,3]
- if currentUsedVertListSmoothGroup[vIdxLs[i]] == 0:
+ if currentUsedVertListSmoothGroup[vIdxLs[i]] == -1:
faceQuadVList[i] = vertList[vIdxLs[i]]
currentMesh.verts.append(faceQuadVList[i])
currentUsedVertListSmoothGroup[vIdxLs[i]] = len(currentMesh.verts)-1
@@ -699,7 +513,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
badObjFaceVerts+=1
else:
for k, j in [(0,0), (1,i+1), (2,i+2)]:
- if currentUsedVertListSmoothGroup[vIdxLs[j]] == 0:
+ if currentUsedVertListSmoothGroup[vIdxLs[j]] == -1:
faceTriVList[k] = vertList[vIdxLs[j]]
currentMesh.verts.append(faceTriVList[k])
currentUsedVertListSmoothGroup[vIdxLs[j]] = len(currentMesh.verts)-1
@@ -827,17 +641,15 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
except KeyError: # Not in dict, add for first time.
# Image has not been added, Try and load the image
- currentImg = comprehansiveImageLoad(newImgName, DIR) # Use join in case of spaces
+ currentImg = BPyImage.comprehansiveImageLoad(newImgName, DIR) # Use join in case of spaces
imageDict[newImgName] = currentImg
# These may be None, thats okay.
-
-
# MATERIAL FILE
elif l[0] == 'mtllib':
mtl_fileName.append(' '.join(l[1:]) ) # SHOULD SUPPORT MULTIPLE MTL?
- #lIdx+=1
-
+ lIdx+=1
+
# Applies material properties to materials alredy on the mesh as well as Textures.
if IMPORT_MTL:
for mtl in mtl_fileName:
@@ -851,7 +663,6 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0):
# Ignore no vert meshes.
if not nme.verts: # == []
continue
-
name = getUniqueName(mk)
ob = NMesh.PutRaw(nme, name)
ob.name = name
@@ -938,12 +749,12 @@ def load_obj_ui(file):
if count > 1:
print 'Total obj import "%s" dir: %.2f' % (obj_dir, sys.time() - time)
-
+
def main():
Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ')
-
-
if __name__ == '__main__':
- main() \ No newline at end of file
+ main()
+
+#load_obj('/cube.obj') \ No newline at end of file