Skip to content
Snippets Groups Projects
import_obj.py 49.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • Campbell Barton's avatar
    Campbell Barton committed
        context_smooth_group = None
        context_object = None
    
        context_vgroup = None
    
        # Nurbs
        context_nurbs = {}
        nurbs = []
    
        context_parm = b''  # used by nurbs too but could be used elsewhere
    
    Campbell Barton's avatar
    Campbell Barton committed
        has_ngons = False
    
        # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0
    
        # Until we can use sets
    
    Campbell Barton's avatar
    Campbell Barton committed
        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''
    
    Campbell Barton's avatar
    Campbell Barton committed
        time_sub = time.time()
    
        file = open(filepath, 'rb')
    
    Campbell Barton's avatar
    Campbell Barton committed
        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 "):
    
    Campbell Barton's avatar
    Campbell Barton committed
                line_split = line.split()
    
    Campbell Barton's avatar
    Campbell Barton committed
                verts_loc.append((float_func(line_split[1]), -float_func(line_split[3]), float_func(line_split[2])))
    
            elif line.startswith(b"vn "):
    
            elif line.startswith(b"vt "):
    
    Campbell Barton's avatar
    Campbell Barton committed
                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':
    
                    # use face_vert_loc_indices and face_vert_tex_indices previously defined and used the obj_face
    
    Campbell Barton's avatar
    Campbell Barton committed
                    line_split = line.split()
    
    Campbell Barton's avatar
    Campbell Barton committed
                    line_split = line[2:].split()
                    face_vert_loc_indices = []
                    face_vert_tex_indices = []
    
                    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'
    
                    context_multi_line = b''
    
                    obj_vert = v.split(b'/')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    vert_loc_index = int(obj_vert[0]) - 1
    
                    # 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
    
    Campbell Barton's avatar
    Campbell Barton committed
                        vert_loc_index = len(verts_loc) + vert_loc_index + 1
    
                    face_vert_loc_indices.append(vert_loc_index)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    if len(obj_vert) > 1 and obj_vert[1]:
    
                        # formatting for faces with normals and textures us
                        # loc_index/tex_index/nor_index
    
    
    Campbell Barton's avatar
    Campbell Barton committed
                        vert_tex_index = int(obj_vert[1]) - 1
    
                        # Make relative negative vert indices absolute
    
    Campbell Barton's avatar
    Campbell Barton committed
                            vert_tex_index = len(verts_tex) + vert_tex_index + 1
    
                        face_vert_tex_indices.append(vert_tex_index)
    
                        face_vert_tex_indices.append(0)
    
                if len(face_vert_loc_indices) > 4:
    
    Campbell Barton's avatar
    Campbell Barton committed
                    has_ngons = True
    
            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
    
    Campbell Barton's avatar
    Campbell Barton committed
                    line_split = line.split()
    
    Campbell Barton's avatar
    Campbell Barton committed
                    line_split = line[2:].split()
                    face_vert_loc_indices = []
                    face_vert_tex_indices = []
    
                    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'
    
                    context_multi_line = b''
    
                isline = line.startswith(b'l')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    vert_loc_index = int(v) - 1
    
                    # Make relative negative vert indices absolute
    
    Campbell Barton's avatar
    Campbell Barton committed
                        vert_loc_index = len(verts_loc) + vert_loc_index + 1
    
                    face_vert_loc_indices.append(vert_loc_index)
    
            elif line.startswith(b's'):
    
    Campbell Barton's avatar
    Campbell Barton committed
                    context_smooth_group = line_value(line.split())
    
                    if context_smooth_group == b'off':
    
    Campbell Barton's avatar
    Campbell Barton committed
                        context_smooth_group = None
                    elif context_smooth_group:  # is not None
                        unique_smooth_groups[context_smooth_group] = None
    
            elif line.startswith(b'o'):
    
    Campbell Barton's avatar
    Campbell Barton committed
                    context_object = line_value(line.split())
    
                    # unique_obects[context_object]= None
    
    
            elif line.startswith(b'g'):
    
    Campbell Barton's avatar
    Campbell Barton committed
                    context_object = line_value(line.split())
    
                    # 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:
    
    Campbell Barton's avatar
    Campbell Barton committed
                        context_vgroup = None  # dont assign a vgroup
    
            elif line.startswith(b'usemtl'):
    
    Campbell Barton's avatar
    Campbell Barton committed
                context_material = line_value(line.split())
                unique_materials[context_material] = None
    
            elif line.startswith(b'mtllib'):  # usemap or usemat
    
    Campbell Barton's avatar
    Campbell Barton committed
                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
    
            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':
    
    Campbell Barton's avatar
    Campbell Barton committed
                line_split = line.split()
    
                curv_idx = context_nurbs[b'curv_idx'] = context_nurbs.get(b'curv_idx', [])  # incase were multiline
    
                    context_nurbs[b'curv_range'] = float_func(line_split[1]), float_func(line_split[2])
    
    Campbell Barton's avatar
    Campbell Barton committed
                    line_split[0:3] = []  # remove first 3 items
    
                    context_multi_line = b'curv'
    
                    context_multi_line = b''
    
    Campbell Barton's avatar
    Campbell Barton committed
                    vert_loc_index = int(i) - 1
    
    Campbell Barton's avatar
    Campbell Barton committed
                        vert_loc_index = len(verts_loc) + vert_loc_index + 1
    
            elif line.startswith(b'parm') or context_multi_line == b'parm':
    
    Campbell Barton's avatar
    Campbell Barton committed
                line_split = line.split()
    
                    context_multi_line = b''
    
    Campbell Barton's avatar
    Campbell Barton committed
                    line_split[0:2] = []  # remove first 2
    
                    context_multi_line = b'parm'
    
                    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 = {}
    
            elif line.startswith(b'usema'): # usemap or usemat
    
                context_image= line_value(line.split())
            '''
    
        file.close()
    
    Campbell Barton's avatar
    Campbell Barton committed
        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)
    
    
    Campbell Barton's avatar
    Campbell Barton committed
        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 = []
    
    Campbell Barton's avatar
    Campbell Barton committed
        new_objects = []  # put new objects here
    
    Campbell Barton's avatar
    Campbell Barton committed
        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
    
    Campbell Barton's avatar
    Campbell Barton committed
        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()
    
    
    Campbell Barton's avatar
    Campbell Barton committed
        axis_min = [1000000000] * 3
        axis_max = [-1000000000] * 3
    
        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
    
    
    Campbell Barton's avatar
    Campbell Barton committed
        time_new = time.time()
    
    Campbell Barton's avatar
    Campbell Barton committed
        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()