fixed an obscure bug in obj import (possibly in Mesh.c) that made adding edges as faces mess up.

export obj now dosnt remove double UV's, its too slow.

updated version numbers to 243 and other minor changes.
This commit is contained in:
Campbell Barton 2007-01-26 06:02:21 +00:00
parent c1bf780dd7
commit 0decfd140b
3 changed files with 40 additions and 39 deletions

@ -2,7 +2,7 @@
""" """
Name: '3D Studio (.3ds)...' Name: '3D Studio (.3ds)...'
Blender: 241 Blender: 243
Group: 'Export' Group: 'Export'
Tooltip: 'Export to 3DS file format (.3ds).' Tooltip: 'Export to 3DS file format (.3ds).'
""" """

@ -2,14 +2,14 @@
""" """
Name: 'Wavefront (.obj)...' Name: 'Wavefront (.obj)...'
Blender: 232 Blender: 243
Group: 'Export' Group: 'Export'
Tooltip: 'Save a Wavefront OBJ File' Tooltip: 'Save a Wavefront OBJ File'
""" """
__author__ = "Campbell Barton, Jiri Hnidek" __author__ = "Campbell Barton, Jiri Hnidek"
__url__ = ["blender", "elysiun"] __url__ = ['www.blender.org', 'blenderartists.org']
__version__ = "1.0" __version__ = "1.1"
__bpydoc__ = """\ __bpydoc__ = """\
This script is an exporter to OBJ file format. This script is an exporter to OBJ file format.
@ -50,7 +50,6 @@ import Blender
from Blender import Mesh, Scene, Window, sys, Image, Draw from Blender import Mesh, Scene, Window, sys, Image, Draw
import BPyMesh import BPyMesh
import BPyObject import BPyObject
reload(BPyObject)
import BPyMessages import BPyMessages
@ -112,11 +111,11 @@ def write_mtl(filename):
else: else:
mat = Blender.Material.Get(key[0]) mat = Blender.Material.Get(key[0])
file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's
file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.getAmb() for c in worldAmb]) ) # Ambient, uses mirror colour, file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour,
file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.getRef() for c in mat.getRGBCol()]) ) # Diffuse file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse
file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.getSpec() for c in mat.getSpecCol()]) ) # Specular file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular
file.write('Ni %.6f\n' % mat.getIOR()) # Refraction index file.write('Ni %.6f\n' % mat.IOR) # Refraction index
file.write('d %.6f\n' % mat.getAlpha()) # Alpha (obj uses 'd' for dissolve) file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
# 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting. # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
if mat.getMode() & Blender.Material.Modes['SHADELESS']: if mat.getMode() & Blender.Material.Modes['SHADELESS']:
@ -246,7 +245,8 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
# Initialize totals, these are updated each object # Initialize totals, these are updated each object
totverts = totuvco = totno = 1 totverts = totuvco = totno = 1
globalUVCoords = {} face_vert_index = 1 # used for uvs now
globalNormals = {} globalNormals = {}
# Get all meshs # Get all meshs
@ -262,8 +262,6 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
# We have a valid mesh # We have a valid mesh
if EXPORT_TRI and me.faces: if EXPORT_TRI and me.faces:
# Add a dummy object to it. # Add a dummy object to it.
oldmode = Mesh.Mode()
Mesh.Mode(Mesh.SelectModes['FACE'])
has_quads = False has_quads = False
for f in me.faces: for f in me.faces:
if len(f) == 4: if len(f) == 4:
@ -271,12 +269,16 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
break break
if has_quads: if has_quads:
oldmode = Mesh.Mode()
Mesh.Mode(Mesh.SelectModes['FACE'])
me.sel = True me.sel = True
tempob = scn.objects.new(me) tempob = scn.objects.new(me)
me.quadToTriangle(0) # more=0 shortest length me.quadToTriangle(0) # more=0 shortest length
oldmode = Mesh.Mode(oldmode) oldmode = Mesh.Mode(oldmode)
scn.objects.unlink(tempob) scn.objects.unlink(tempob)
Mesh.Mode(oldmode)
Mesh.Mode(oldmode)
# Make our own list so it can be sorted to reduce context switching # Make our own list so it can be sorted to reduce context switching
faces = [ f for f in me.faces ] faces = [ f for f in me.faces ]
@ -349,12 +351,8 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
# UV # UV
if faceuv and EXPORT_UV: if faceuv and EXPORT_UV:
for f in faces: for f in faces:
for uvKey in f.uv: for uv in f.uv:
uvKey = veckey2d(uvKey) file.write('vt %.6f %.6f 0.0\n' % tuple(uv))
if not globalUVCoords.has_key(uvKey):
globalUVCoords[uvKey] = totuvco
totuvco +=1
file.write('vt %.6f %.6f 0.0\n' % uvKey)
# NORMAL, Smooth/Non smoothed. # NORMAL, Smooth/Non smoothed.
if EXPORT_NORMALS: if EXPORT_NORMALS:
@ -374,7 +372,6 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
totno +=1 totno +=1
file.write('vn %.6f %.6f %.6f\n' % noKey) file.write('vn %.6f %.6f %.6f\n' % noKey)
uvIdx = 0
for f in faces: for f in faces:
f_v= f.v f_v= f.v
if faceuv: if faceuv:
@ -425,10 +422,10 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
if f.smooth != contextSmooth: if f.smooth != contextSmooth:
if contextSmooth: # on now off if contextSmooth: # on now off
file.write('s off\n') file.write('s off\n')
contextSmooth = True
else: # was off now on else: # was off now on
file.write('s 1\n') file.write('s 1\n')
contextSmooth = False
contextSmooth = f.smooth
file.write('f') file.write('f')
if faceuv and EXPORT_UV: if faceuv and EXPORT_UV:
@ -437,22 +434,24 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False):
for vi, v in enumerate(f_v): for vi, v in enumerate(f_v):
file.write( ' %d/%d/%d' % (\ file.write( ' %d/%d/%d' % (\
v.index+totverts,\ v.index+totverts,\
globalUVCoords[ veckey2d(f_uv[vi]) ],\ face_vert_index + vi,\
globalNormals[ veckey3d(v.no) ])) # vert, uv, normal globalNormals[ veckey3d(v.no) ])) # vert, uv, normal
else: # No smoothing, face normals else: # No smoothing, face normals
no = globalNormals[ veckey3d(f.no) ] no = globalNormals[ veckey3d(f.no) ]
for vi, v in enumerate(f_v): for vi, v in enumerate(f_v):
file.write( ' %d/%d/%d' % (\ file.write( ' %d/%d/%d' % (\
v.index+totverts,\ v.index+totverts,\
globalUVCoords[ veckey2d(f_uv[vi]) ],\ face_vert_index + vi,\
no)) # vert, uv, normal no)) # vert, uv, normal
else: # No Normals else: # No Normals
for vi, v in enumerate(f_v): for vi, v in enumerate(f_v):
file.write( ' %d/%d' % (\ file.write( ' %d/%d' % (\
v.index+totverts,\ v.index+totverts,\
globalUVCoords[ veckey2d(f_uv[vi])])) # vert, uv face_vert_index + vi)) # vert, uv
face_vert_index += len(f_v)
else: # No UV's else: # No UV's
if EXPORT_NORMALS: if EXPORT_NORMALS:
@ -616,7 +615,7 @@ def write_ui(filename):
export_objects = scn.objects export_objects = scn.objects
full_path= ''.join(context_name) full_path= ''.join(context_name)
print "ass", full_path
if BPyMessages.Warning_SaveOver(full_path): if BPyMessages.Warning_SaveOver(full_path):
# EXPORT THE FILE. # EXPORT THE FILE.
write(full_path, export_objects,\ write(full_path, export_objects,\

@ -248,7 +248,7 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OBJECTS, SPLI
face_split_dict= {} face_split_dict= {}
oldkey= -1 # initialize to a value what will never match the key oldkey= -1 # initialize to a value that will never match the key
for face in faces: for face in faces:
@ -326,17 +326,17 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
if len_face_vert_loc_indicies==1: if len_face_vert_loc_indicies==1:
faces.pop(f_idx)# cant add single vert faces faces.pop(f_idx)# cant add single vert faces
elif not face_vert_tex_indicies: # images that are -1 are lines, a bit obscure but works. elif not face_vert_tex_indicies or len_face_vert_loc_indicies == 2: # faces that have no texture coords are lines
if CREATE_EDGES: if CREATE_EDGES:
# generators are better in python 2.4+ but can't be used in 2.3 # generators are better in python 2.4+ but can't be used in 2.3
# edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) ) # edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) )
edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1)] ) edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1)] )
faces.pop(f_idx) faces.pop(f_idx)
else: else:
# Smooth Group # Smooth Group
if unique_smooth_groups and context_smooth_group and len_face_vert_loc_indicies > 3: if unique_smooth_groups and context_smooth_group:
# Is a part of of a smooth group and is a face # Is a part of of a smooth group and is a face
if context_smooth_group_old is not context_smooth_group: if context_smooth_group_old is not context_smooth_group:
edge_dict= smooth_group_users[context_smooth_group] edge_dict= smooth_group_users[context_smooth_group]
@ -423,13 +423,15 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
ALPHA= Mesh.FaceTranspModes.ALPHA ALPHA= Mesh.FaceTranspModes.ALPHA
for i, face in enumerate(faces): for i, face in enumerate(faces):
if len(face[0]) < 2:
raise "Fooo"
if len(face[0])==2: if len(face[0])==2:
if CREATE_EDGES: if CREATE_EDGES:
edges.append(face[0]) edges.append(face[0])
else: else:
face_index_map= face_mapping[i] face_index_map= face_mapping[i]
if face_index_map!=None: # None means the face wasnt added if face_index_map!=None: # None means the face wasnt added
blender_face= me.faces[face_index_map] blender_face= me_faces[face_index_map]
face_vert_loc_indicies,\ face_vert_loc_indicies,\
face_vert_tex_indicies,\ face_vert_tex_indicies,\
@ -437,6 +439,8 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
context_smooth_group,\ context_smooth_group,\
context_object= face context_object= face
if context_smooth_group: if context_smooth_group:
blender_face.smooth= True blender_face.smooth= True
@ -488,18 +492,17 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
if ed!=None: if ed!=None:
me_edges[ed].flag |= SHARP me_edges[ed].flag |= SHARP
del SHARP del SHARP
del me_edges
if CREATE_EDGES: if CREATE_EDGES:
me.edges.extend( edges ) me_edges.extend( edges )
del me_edges
me.calcNormals() me.calcNormals()
scn= Scene.GetCurrent() scn= Scene.GetCurrent()
ob= scn.objects.new(me) ob= scn.objects.new(me)
new_objects.append(ob) new_objects.append(ob)
ob.sel= 1
def get_float_func(filepath): def get_float_func(filepath):
''' '''
@ -593,7 +596,6 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS
context_smooth_group,\ context_smooth_group,\
context_object\ context_object\
)) ))
if line_split[-1][-1]== '\\': if line_split[-1][-1]== '\\':
multi_line_face= True multi_line_face= True
@ -681,7 +683,7 @@ def load_obj(filepath, CLAMP_SIZE= 0.0, CREATE_FGONS= True, CREATE_SMOOTH_GROUPS
Scene.GetCurrent().objects.selected = [] Scene.GetCurrent().objects.selected = []
new_objects= [] # put new objects here new_objects= [] # put new objects here
print '\tbuilding geometry;\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ), print '\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ),
# Split the mesh by objects/materials, may # Split the mesh by objects/materials, may
for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OBJECTS, SPLIT_MATERIALS): for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OBJECTS, SPLIT_MATERIALS):
# Create meshes from the data # Create meshes from the data