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:
@@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user