Newer
Older
context_nurbs = {}
nurbs = []
context_parm = b'' # used by nurbs too but could be used elsewhere
# has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0
# Until we can use sets
unique_materials = {}
unique_material_images = {}
unique_smooth_groups = {}
# unique_obects= {} - no use for this variable since the objects are stored in the face.
# when there are faces that end with \
# it means they are multiline-
# since we use xreadline we cant skip to the next line
# so we need to know whether
context_multi_line = b''
print("\tparsing obj file...")
# time_sub= sys.time()
file = open(filepath, 'rb')
for line in file: # .readlines():
line = line.lstrip() # rare cases there is white space at the start of the line
if line.startswith(b"v "):
# rotate X90: (x,-z,y)
verts_loc.append((float_func(line_split[1]), -float_func(line_split[3]), float_func(line_split[2])))
elif line.startswith(b"vn "):
pass
elif line.startswith(b"vt "):
line_split = line.split()
verts_tex.append((float_func(line_split[1]), float_func(line_split[2])))
# Handel faces lines (as faces) and the second+ lines of fa multiline face here
# use 'f' not 'f ' because some objs (very rare have 'fo ' for faces)
elif line.startswith(b'f') or context_multi_line == b'f':
if context_multi_line:
# use face_vert_loc_indices and face_vert_tex_indices previously defined and used the obj_face
else:
line_split = line[2:].split()
face_vert_loc_indices = []
face_vert_tex_indices = []
# Instance a face
faces.append((\
face_vert_loc_indices,\
face_vert_tex_indices,\
context_material,\
context_smooth_group,\
context_object\
))
if strip_slash(line_split):
context_multi_line = b'f'
else:
context_multi_line = b''
for v in line_split:
obj_vert = v.split(b'/')
# Add the vertex to the current group
# *warning*, this wont work for files that have groups defined around verts
if POLYGROUPS and context_vgroup:
vertex_groups[context_vgroup].append(vert_loc_index)
# Make relative negative vert indices absolute
if vert_loc_index < 0:
vert_loc_index = len(verts_loc) + vert_loc_index + 1
face_vert_loc_indices.append(vert_loc_index)
# formatting for faces with normals and textures us
# loc_index/tex_index/nor_index
# Make relative negative vert indices absolute
if vert_tex_index < 0:
vert_tex_index = len(verts_tex) + vert_tex_index + 1
face_vert_tex_indices.append(vert_tex_index)
else:
# dummy
face_vert_tex_indices.append(0)
if len(face_vert_loc_indices) > 4:
elif CREATE_EDGES and (line.startswith(b'l ') or context_multi_line == b'l'):
# very similar to the face load function above with some parts removed
if context_multi_line:
# use face_vert_loc_indices and face_vert_tex_indices previously defined and used the obj_face
else:
line_split = line[2:].split()
face_vert_loc_indices = []
face_vert_tex_indices = []
# Instance a face
faces.append((\
face_vert_loc_indices,\
face_vert_tex_indices,\
context_material,\
context_smooth_group,\
context_object\
))
if strip_slash(line_split):
context_multi_line = b'l'
else:
context_multi_line = b''
isline = line.startswith(b'l')
for v in line_split:
# Make relative negative vert indices absolute
if vert_loc_index < 0:
vert_loc_index = len(verts_loc) + vert_loc_index + 1
face_vert_loc_indices.append(vert_loc_index)
elif line.startswith(b's'):
if CREATE_SMOOTH_GROUPS:
if context_smooth_group == b'off':
context_smooth_group = None
elif context_smooth_group: # is not None
unique_smooth_groups[context_smooth_group] = None
elif line.startswith(b'o'):
if SPLIT_OBJECTS:
# unique_obects[context_object]= None
elif line.startswith(b'g'):
if SPLIT_GROUPS:
# print 'context_object', context_object
# unique_obects[context_object]= None
elif POLYGROUPS:
context_vgroup = line_value(line.split())
if context_vgroup and context_vgroup != b'(null)':
vertex_groups.setdefault(context_vgroup, [])
else:
elif line.startswith(b'usemtl'):
context_material = line_value(line.split())
unique_materials[context_material] = None
elif line.startswith(b'mtllib'): # usemap or usemat
material_libs = list(set(material_libs) | set(line.split()[1:])) # can have multiple mtllib filenames per line, mtllib can appear more than once, so make sure only occurance of material exists
# Nurbs support
elif line.startswith(b'cstype '):
context_nurbs[b'cstype'] = line_value(line.split()) # 'rat bspline' / 'bspline'
elif line.startswith(b'curv ') or context_multi_line == b'curv':
curv_idx = context_nurbs[b'curv_idx'] = context_nurbs.get(b'curv_idx', []) # incase were multiline
if not context_multi_line:
context_nurbs[b'curv_range'] = float_func(line_split[1]), float_func(line_split[2])
if strip_slash(line_split):
context_multi_line = b'curv'
else:
context_multi_line = b''
for i in line_split:
if vert_loc_index < 0:
vert_loc_index = len(verts_loc) + vert_loc_index + 1
curv_idx.append(vert_loc_index)
elif line.startswith(b'parm') or context_multi_line == b'parm':
if context_multi_line:
context_multi_line = b''
else:
context_parm = line_split[1]
if strip_slash(line_split):
context_multi_line = b'parm'
else:
context_multi_line = b''
if context_parm.lower() == b'u':
context_nurbs.setdefault(b'parm_u', []).extend([float_func(f) for f in line_split])
elif context_parm.lower() == b'v': # surfaces not suported yet
context_nurbs.setdefault(b'parm_v', []).extend([float_func(f) for f in line_split])
# else: # may want to support other parm's ?
elif line.startswith(b'deg '):
context_nurbs[b'deg'] = [int(i) for i in line.split()[1:]]
elif line.startswith(b'end'):
# Add the nurbs curve
if context_object:
context_nurbs[b'name'] = context_object
nurbs.append(context_nurbs)
context_nurbs = {}
''' # How to use usemap? depricated?
elif line.startswith(b'usema'): # usemap or usemat
context_image= line_value(line.split())
'''
file.close()
time_new = time.time()
print("%.4f sec" % (time_new - time_sub))
time_sub = time_new
print('\tloading materials and images...')
create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH)
time_new = time.time()
print("%.4f sec" % (time_new - time_sub))
time_sub = time_new
if not ROTATE_X90:
verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc]
# deselect all
bpy.ops.object.select_all(action='DESELECT')
scene = context.scene
# scn.objects.selected = []
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
if SPLIT_OBJECTS or SPLIT_GROUPS:
SPLIT_OB_OR_GROUP = True
else:
SPLIT_OB_OR_GROUP = False
for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
# Create meshes from the data, warning 'vertex_groups' wont support splitting
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, vertex_groups, dataname)
# nurbs support
for context_nurbs in nurbs:
create_nurbs(context_nurbs, verts_loc, new_objects)
# Create new obj
for obj in new_objects:
base = scene.objects.link(obj)
base.select = True
scene.update()
axis_min = [1000000000] * 3
axis_max = [-1000000000] * 3
Campbell Barton
committed
if CLAMP_SIZE:
# Get all object bounds
for ob in new_objects:
for v in ob.bound_box:
for axis, value in enumerate(v):
if axis_min[axis] > value:
axis_min[axis] = value
if axis_max[axis] < value:
axis_max[axis] = value
# Scale objects
max_axis = max(axis_max[0] - axis_min[0], axis_max[1] - axis_min[1], axis_max[2] - axis_min[2])
scale = 1.0
while CLAMP_SIZE < max_axis * scale:
scale = scale / 10.0
for obj in new_objects:
obj.scale = scale, scale, scale
# Better rotate the vert locations
#if not ROTATE_X90:
# for ob in new_objects:
# ob.RotX = -1.570796326794896558
print("finished importing: %r in %.4f sec." % (filepath, (time_new - time_main)))
return {'FINISHED'}
# NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
# check later: line 489
# can convert now: edge flags, edges: lines 508-528
# ngon (uses python module BPyMesh): 384-414
# NEXT clamp size: get bound box with RNA
# get back to l 140 (here)
# search image in bpy.config.textureDir - load_image
# replaced BPyImage.comprehensiveImageLoad with a simplified version that only checks additional directory specified, but doesn't search dirs recursively (obj_image_load)
# bitmask won't work? - 132
# uses bpy.sys.time()
if __name__ == "__main__":
register()