OBJ Import should now meet up to the python standards

http://mediawiki.blender.org/index.php/ScriptDev/Guidelines

* Recursive search was enabled by default, if your OBJ happened to be at root path, loading the OBJ could take ages. Made recursive searching optional.
* MAX's MTL exporter replaces spaces with underscores, image loading checks for this and loads the name with spaces if the one with underscores dosnt exist. not realy a problem with the importer but annoying to manually replace lots of images.
This commit is contained in:
2006-09-20 05:03:53 +00:00
parent fd0628c6db
commit 360d7a1083
2 changed files with 84 additions and 55 deletions

View File

@@ -79,7 +79,22 @@ def addSlash(path):
return path + sys.sep return path + sys.sep
def comprehensiveImageLoad(imagePath, filePath, placeHolder= True, VERBOSE=False): def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=True, VERBOSE=False):
'''
imagePath: The image filename
If a path precedes it, this will be searched as well.
filePath: is the directory where the image may be located - any file at teh end will be ignored.
PLACE_HOLDER: if True a new place holder image will be created.
this is usefull so later you can relink the image to its original data.
VERBOSE: If True debug info will be printed.
RECURSIVE: If True, directories will be recursivly searched.
Be carefull with this if you have files in your root directory because it may take a long time.
'''
if VERBOSE: print 'img:', imagePath, 'file:', filePath if VERBOSE: print 'img:', imagePath, 'file:', filePath
# When we have the file load it with this. try/except niceness. # When we have the file load it with this. try/except niceness.
def imageLoad(path): def imageLoad(path):
@@ -91,11 +106,10 @@ def comprehensiveImageLoad(imagePath, filePath, placeHolder= True, VERBOSE=False
if VERBOSE: print '\t\tImage loaded "%s"' % path if VERBOSE: print '\t\tImage loaded "%s"' % path
return img return img
except: except:
#raise "Helloo"
if VERBOSE: if VERBOSE:
if sys.exists(path): print '\t\tImage failed loading "%s", mabe its not a format blender can read.' % (path) if sys.exists(path): print '\t\tImage failed loading "%s", mabe its not a format blender can read.' % (path)
else: print '\t\tImage not found, making a place holder "%s"' % (path) else: print '\t\tImage not found, making a place holder "%s"' % (path)
if placeHolder: if PLACE_HOLDER:
img= Blender.Image.New(stripPath(path),1,1,24) img= Blender.Image.New(stripPath(path),1,1,24)
img.filename= path img.filename= path
return img #blank image return img #blank image
@@ -140,7 +154,7 @@ def comprehensiveImageLoad(imagePath, filePath, placeHolder= True, VERBOSE=False
# os needed if we go any further. # os needed if we go any further.
if os == None: if not os:
if VERBOSE: print '\t\tCreating a placeholder with a face path: "%s".' % imagePath if VERBOSE: print '\t\tCreating a placeholder with a face path: "%s".' % imagePath
return imageLoad(imagePath) # Will jus treturn a placeholder. return imageLoad(imagePath) # Will jus treturn a placeholder.
@@ -233,58 +247,53 @@ def comprehensiveImageLoad(imagePath, filePath, placeHolder= True, VERBOSE=False
if VERBOSE: print '\t\tImage Found "%s"' % tmpPath if VERBOSE: print '\t\tImage Found "%s"' % tmpPath
return img return img
if RECURSIVE:
# IMAGE NOT FOUND IN ANY OF THE DIRS!, DO A RECURSIVE SEARCH. # IMAGE NOT FOUND IN ANY OF THE DIRS!, DO A RECURSIVE SEARCH.
if VERBOSE: print '\t\tImage Not Found in any of the dirs, doing a recusrive search' if VERBOSE: print '\t\tImage Not Found in any of the dirs, doing a recusrive search'
for path in paths.iterkeys(): for path in paths.iterkeys():
# Were not going to use files # 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)
if VERBOSE: 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]) )
if VERBOSE: print '\t\tFound "%s"' % matchList[0][0] #------------------
# finds the file starting at the root.
# def findImage(findRoot, imagePath):
#W---------------
# Loop through all we have found # ROOT, DIRS, FILES
img = None pathWalk = os.walk(path)
for match in matchList: pathList = [True]
img = imageLoad(match[0]) # 0 - first, 0 - pathname
if img != None: matchList = [] # Store a list of (match, size), choose the biggest.
while True:
try:
pathList = pathWalk.next()
except:
break break
return img
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)
if VERBOSE: 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]) )
if VERBOSE: 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. # No go.
if VERBOSE: print '\t\tImage Not Found after looking everywhere! "%s"' % imagePath if VERBOSE: print '\t\tImage Not Found after looking everywhere! "%s"' % imagePath
return imageLoad(imagePath) # Will jus treturn a placeholder. return imageLoad(imagePath) # Will jus treturn a placeholder.

View File

@@ -56,8 +56,24 @@ def line_value(line_split):
elif length > 2: elif length > 2:
return ' '.join( line_split[1:] ) return ' '.join( line_split[1:] )
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
'''
Mainly uses comprehensiveImageLoad
but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
'''
if '_' in imagepath:
image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
if image: return image
# Did the exporter rename the image?
image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
if image: return image
# Return an image, placeholder if it dosnt exist
image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
return image
def create_materials(filepath, material_libs, unique_materials, unique_material_images): def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH):
'''Create all the used materials in this obj, '''Create all the used materials in this obj,
assign colors and images to the materials from all referenced material libs''' assign colors and images to the materials from all referenced material libs'''
DIR= stripFile(filepath) DIR= stripFile(filepath)
@@ -71,7 +87,7 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
texture.setType('Image') texture.setType('Image')
# Absolute path - c:\.. etc would work here # Absolute path - c:\.. etc would work here
image= BPyImage.comprehensiveImageLoad(imagepath, DIR) image= obj_image_load(imagepath, DIR, IMAGE_SEARCH)
# Adds textures for materials (rendering) # Adds textures for materials (rendering)
if type == 'Kd': if type == 'Kd':
@@ -454,7 +470,7 @@ def get_float_func(filepath):
elif '.' in line: elif '.' in line:
return float return float
def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS= True, CREATE_EDGES= True, SPLIT_OBJECTS= True, SPLIT_GROUPS= True, SPLIT_MATERIALS= True): def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS= True, CREATE_EDGES= True, SPLIT_OBJECTS= True, SPLIT_GROUPS= True, SPLIT_MATERIALS= True, IMAGE_SEARCH=True):
print '\nimporting obj "%s"' % filepath print '\nimporting obj "%s"' % filepath
@@ -605,7 +621,7 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS
print '\tloading materials and images...', print '\tloading materials and images...',
create_materials(filepath, material_libs, unique_materials, unique_material_images) create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH)
time_new= sys.time() time_new= sys.time()
print '%.4f sec' % (time_new-time_sub) print '%.4f sec' % (time_new-time_sub)
@@ -660,6 +676,7 @@ def load_obj_ui(filepath):
SPLIT_GROUPS= Draw.Create(1) SPLIT_GROUPS= Draw.Create(1)
SPLIT_MATERIALS= Draw.Create(1) SPLIT_MATERIALS= Draw.Create(1)
CLAMP_SIZE= Draw.Create(10.0) CLAMP_SIZE= Draw.Create(10.0)
IMAGE_SEARCH= Draw.Create(1)
# Get USER Options # Get USER Options
@@ -671,6 +688,8 @@ def load_obj_ui(filepath):
('Split by Groups', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\ ('Split by Groups', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\
('Split by Material', SPLIT_MATERIALS, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)'),\ ('Split by Material', SPLIT_MATERIALS, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)'),\
('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\ ('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\
'',\
('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\
] ]
if not Draw.PupBlock('Import OBJ...', pup_block): if not Draw.PupBlock('Import OBJ...', pup_block):
@@ -686,6 +705,7 @@ def load_obj_ui(filepath):
SPLIT_OBJECTS.val,\ SPLIT_OBJECTS.val,\
SPLIT_GROUPS.val,\ SPLIT_GROUPS.val,\
SPLIT_MATERIALS.val,\ SPLIT_MATERIALS.val,\
IMAGE_SEARCH.val,\
) )
Window.WaitCursor(0) Window.WaitCursor(0)