forked from bartvdbraak/blender
BPyMessages - added "Save over" message for scripts to use, so as not to overwrite files.
import_obj - comments, docstring additions, cleanup. OBJ export: -renamed export_obj faster edge exporting (use edges LOOSE flag rather then finding zero face user edges) check for file before overwriting use object iterators
This commit is contained in:
parent
db7c3d3271
commit
7fce181d11
@ -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
|
||||
|
@ -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.
|
||||
@ -380,7 +381,6 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
|
||||
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:
|
||||
pass # Context alredy switched, dont do anythoing
|
||||
@ -468,19 +468,10 @@ 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)
|
||||
@ -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,12 +594,15 @@ 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()
|
||||
|
||||
full_path= ''.join(context_name)
|
||||
|
||||
if BPyMessages.Warning_SaveOver(full_path):
|
||||
# EXPORT THE FILE.
|
||||
write(''.join(context_name), export_objects,\
|
||||
write(full_path, export_objects,\
|
||||
EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\
|
||||
EXPORT_NORMALS_HQ, EXPORT_UV, EXPORT_MTL,\
|
||||
EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user