diff --git a/release/scripts/bpymodules/BPyMessages.py b/release/scripts/bpymodules/BPyMessages.py index 425bbc06d01..2ac6291926c 100644 --- a/release/scripts/bpymodules/BPyMessages.py +++ b/release/scripts/bpymodules/BPyMessages.py @@ -1,4 +1,4 @@ -from Blender import Draw +from Blender import Draw, sys def Error_NoMeshSelected(): Draw.PupMenu('ERROR%t|No mesh objects selected') def Error_NoMeshActive(): @@ -8,3 +8,11 @@ def Error_NoMeshUvSelected(): def Error_NoMeshUvActive(): Draw.PupMenu('ERROR%t|Active object is not a mesh with texface') +def Warning_SaveOver(path): + '''Returns - True to save, False dont save''' + if sys.exists(sys.expandpath(path)): + ret= Draw.PupMenu('Save over%t|' + path) + if ret == -1: + return False + + return True diff --git a/release/scripts/obj_export.py b/release/scripts/export_obj.py similarity index 93% rename from release/scripts/obj_export.py rename to release/scripts/export_obj.py index a58628477ce..53f6550d3e8 100644 --- a/release/scripts/obj_export.py +++ b/release/scripts/export_obj.py @@ -16,7 +16,10 @@ This script is an exporter to OBJ file format. Usage: -Run this script from "File->Export" menu to export all meshes. +Select the objects you wish to export and run this script from "File->Export" menu. +Selecting the default options from the popup box will be good in most cases. +All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d) +will be exported as mesh data. """ @@ -46,6 +49,7 @@ Run this script from "File->Export" menu to export all meshes. import Blender from Blender import Mesh, Scene, Window, sys, Image, Draw import BPyMesh +import BPyMessages # Returns a tuple - path,extension. # 'hello.obj' > ('hello', '.obj') @@ -68,9 +72,6 @@ def saneFilechars(name): name = name.replace(ch, '_') return name -def sortPair(a,b): - return min(a,b), max(a,b) - global MTL_DICT # A Dict of Materials @@ -217,7 +218,7 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): file = open(filename, "w") # Write Header - file.write('# Blender v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) + file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) file.write('# www.blender3d.org\n') # Tell the obj file what material file to use. @@ -379,7 +380,6 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): else: key = materialNames[min(f.mat,len(materialNames)-1)], None # No image, use None instead. #key = materialNames[f.mat], None # No image, use None instead. - # CHECK FOR CONTEXT SWITCH if key == contextMat: @@ -468,20 +468,11 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): # Write edges. if EXPORT_EDGES: - edgeUsers = {} - for f in faces: - for i in xrange(len(f_v)): - faceEdgeVKey = sortPair(f_v[i].index, f_v[i-1].index) - - # We dont realy need to keep count. Just that a face uses it - # so dont export. - edgeUsers[faceEdgeVKey] = 1 - + LOOSE= Mesh.EdgeFlags.LOOSE for ed in edges: - edgeVKey = sortPair(ed.v1.index, ed.v2.index) - if not edgeUsers.has_key(edgeVKey): # No users? Write the edge. - file.write('f %d %d\n' % (edgeVKey[0]+totverts, edgeVKey[1]+totverts)) - + if ed.flag & LOOSE: + file.write('f %d %d\n' % (ed.v1.index+totverts, ed.v2.index+totverts)) + # Make the indicies global rather then per mesh totverts += len(m.verts) m.verts= None @@ -507,9 +498,6 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): def write_ui(filename): - for s in Window.GetScreenInfo(): - Window.QHandle(s['id']) - EXPORT_APPLY_MODIFIERS = Draw.Create(1) EXPORT_ROTX90 = Draw.Create(1) EXPORT_TRI = Draw.Create(0) @@ -552,6 +540,7 @@ def write_ui(filename): if not Draw.PupBlock('Export...', pup_block): return + Window.EditMode(0) Window.WaitCursor(1) EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val @@ -594,7 +583,7 @@ def write_ui(filename): # Export an animation? if EXPORT_ANIMATION: - scene_frames = range(context.startFrame(), context.endFrame()+1) # up to and including the end frame. + scene_frames = xrange(context.startFrame(), context.endFrame()+1) # up to and including the end frame. else: scene_frames = [orig_frame] # Dont export an animation. @@ -605,17 +594,20 @@ def write_ui(filename): Blender.Set('curframe', frame) if EXPORT_SEL_ONLY: - export_objects = Blender.Object.GetSelected() # Export Context + export_objects = scn.objects.selected #Blender.Object.GetSelected() # Export Context else: - export_objects = scn.getChildren() + export_objects = scn.objects # scn.getChildren() - # EXPORT THE FILE. - write(''.join(context_name), export_objects,\ - EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\ - EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\ - EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ - EXPORT_ROTX90, EXPORT_BLEN_OBS,\ - EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT) + full_path= ''.join(context_name) + + if BPyMessages.Warning_SaveOver(full_path): + # EXPORT THE FILE. + write(full_path, export_objects,\ + EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\ + EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\ + EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ + EXPORT_ROTX90, EXPORT_BLEN_OBS,\ + EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT) Blender.Set('curframe', orig_frame) diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py index 3df0a67c425..6849121934e 100644 --- a/release/scripts/import_obj.py +++ b/release/scripts/import_obj.py @@ -12,17 +12,19 @@ __url__= ["blender.org", "blenderartists.org"] __version__= "2.0" __bpydoc__= """\ -This script imports OBJ files to Blender. +This script imports a Wavefront OBJ files to Blender. Usage: Run this script from "File->Import" menu and then load the desired OBJ file. -Note, This loads mesh objects and materials only, nurbs and curves are unsupported. +Note, This loads mesh objects and materials only, nurbs and curves are not supported. """ from Blender import * import BPyMesh import BPyImage + +# Generic path functions def stripFile(path): '''Return directory, where the file is''' lastSlash= max(path.rfind('\\'), path.rfind('/')) @@ -30,9 +32,8 @@ def stripFile(path): path= path[:lastSlash] return '%s%s' % (path, sys.sep) -# Generic path functions def stripPath(path): - # Strips the slashes from the back of a string + '''Strips the slashes from the back of a string''' return path.split('/')[-1].split('\\')[-1] def stripExt(name): # name is a string @@ -44,8 +45,13 @@ def stripExt(name): # name is a string return name # end path funcs + + def line_value(line_split): - '''Takes removes the first work from the line, None if theres only1 word''' + ''' + Returns 1 string represneting the value for this line + None will be returned if theres only 1 word + ''' length= len(line_split) if length == 1: return None @@ -75,8 +81,10 @@ def obj_image_load(imagepath, DIR, IMAGE_SEARCH): def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH): - '''Create all the used materials in this obj, - assign colors and images to the materials from all referenced material libs''' + ''' + Create all the used materials in this obj, + assign colors and images to the materials from all referenced material libs + ''' DIR= stripFile(filepath) #==================================================================================# @@ -184,6 +192,12 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ def split_mesh(verts_loc, faces, unique_materials, SPLIT_OBJECTS, SPLIT_MATERIALS): + ''' + Takes vert_loc and faces, and seperates into multiple sets of + (verts_loc, faces, unique_materials) + This is done so objects do not overload the 16 material limit. + ''' + if not SPLIT_OBJECTS and not SPLIT_MATERIALS: return [(verts_loc, faces, unique_materials)] @@ -248,8 +262,11 @@ def split_mesh(verts_loc, faces, unique_materials, SPLIT_OBJECTS, SPLIT_MATERIAL return [(verts_split, faces_split, unique_materials_split) for faces_split, verts_split, unique_materials_split, vert_remap in face_split_dict.itervalues()] -def create_meshes(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups): - +def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups): + ''' + Takes all the data gathered and generates a mesh, adding the new object to new_objects + deals with fgons, sharp edges and assigning materials + ''' if not has_ngons: CREATE_FGONS= False @@ -363,10 +380,6 @@ def create_meshes(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, me.materials= materials[0:16] # make sure the list isnt too big. #me.verts.extend([(0,0,0)]) # dummy vert me.verts.extend(verts_loc) - for f in faces: - if len(f[0]) not in (3,4): - print len(f[0]) - raise "Error" face_mapping= me.faces.extend([f[0] for f in faces], indexList=True) @@ -472,7 +485,12 @@ def get_float_func(filepath): 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, IMAGE_SEARCH=True): - + ''' + Called by the user interface or another script. + load_obj(path) - should give acceptable results. + This function passes the file and sends the data off + to be split into objects and then converted into mesh objects + ''' print '\nimporting obj "%s"' % filepath time_main= sys.time() @@ -637,7 +655,7 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS # Split the mesh by objects/materials, may for verts_loc_split, faces_split, unique_materials_split in split_mesh(verts_loc, faces, unique_materials, SPLIT_OBJECTS, SPLIT_MATERIALS): # Create meshes from the data - create_meshes(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups) + create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups) axis_min= [ 1000000000]*3 axis_max= [-1000000000]*3