Exemplo n.º 1
0
def readMesh(filename, objName):
    file = open(filename, "rb")

    def line_to_face(line):
        # Each triplet is an xyz float
        line_split = []
        try:
            line_split = list(map(float, line.split()))
        except:
            return None

        if len(line_split) == 9: # Tri
            f1, f2, f3, f4, f5, f6, f7, f8, f9 = line_split
            return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9)]
        elif len(line_split) == 12: # Quad
            f1, f2, f3, f4, f5, f6, f7, f8, f9, A, B, C = line_split
            return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9), (A, B, C)]
        else:
            return None


    faces = []
    for line in file.readlines():
        face = line_to_face(line)
        if face:
            faces.append(face)

    file.close()

    # Generate verts and faces lists, without duplicates
    verts = []
    coords = {}
    index_tot = 0
    
    for f in faces:
        for i, v in enumerate(f):
            index = coords.get(v)

            if index is None:
                index = coords[v] = index_tot
                index_tot += 1
                verts.append(v)

            fi[i] = index

    mesh = bpy.data.meshes.new(objName)
    mesh.vertices.add(len(verts))
    mesh.faces.add(len(faces))
    mesh.vertices.foreach_set("co", unpack_list(verts))
    mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))

    return mesh
def read_shape(data,use_subsurf,use_hidden):
  read_tuple_header(data)
  skip_token(data) #object
  shape_name = read_token(data)
  print ("shape: ",shape_name)
  read_tuple_header(data)
  skip_token(data) #winged

  #read mesh data
  edge_table = read_array(data,read_edge_set)
  print("edge_table: ",edge_table)
  face_props = read_array(data,read_array_as_dict)
  print("face_mats: ",face_props)
  verts = read_array(data,read_vertex_array)
  print("verts: ",verts)
  hard_edges = read_array(data)
  print("hard_edges: ",hard_edges)
  props = read_array_as_dict(data,read_prop)
  print("props: ",props)

  # if we are ignoring hidden objects
  # we can stop now
  if use_hidden == True and b'state' in props:
    state = props[b'state']
    if state == b'hidden' or state == b'hidden_locked':
      return

  # make a list of edges with just the vert part
  # of the list eg [(v0,v1),(v0,v1)...]
  edges = get_edges(edge_table)
  print("edges: ",edges)

  # build a list of faces from edge data,
  # also vertex colors, face_uvs and a few other bits
  # and pieces
  faces,face_cols,face_uvs,hide_edges,mirror_face = faces_from_edge_table(edge_table,verts,props,face_props,edges)
  print("edges: ",edges)
  print("faces: ",faces)
  print("colors: ",face_cols)
  print("uvs: ",face_uvs)
  print("hide edges: ",hide_edges)

  #create bleneder mesh
  me = bpy.data.meshes.new(shape_name)
  ob = bpy.data.objects.new(shape_name,me)
  bpy.context.scene.objects.link(ob)
  me.vertices.add(len(verts))
  me.vertices.foreach_set("co", unpack_list(verts))
  me.faces.add(len(faces))
  me.faces.foreach_set("vertices_raw",unpack_face_list(faces))
  me.edges.add(len(edges))
  me.edges.foreach_set("vertices",unpack_list(edges))
  me.validate()
 # me.update(calc_edges=True)

  #add edges to blender mesh, mark special edges
  #b_edges = me.edges
  #for i in range(len(b_edges)):
    #(v0,v1) = b_edges[i].vertices
    #print("edge ", i, " ",v0,"-",v1)

  build_hard_edges(me,hard_edges)
  hide_fgon_edges(me,hide_edges)

  if len(face_cols) > 0: build_face_colors(me,face_cols)
  if len(face_uvs) > 0: build_face_uvs(me,face_uvs)
  for i in range(len(faces)): me.faces[i].use_smooth = True
  add_material_indices(me,face_props)

  mods = ob.modifiers
  if use_subsurf == True:
    mod = mods.new("subsurf",'SUBSURF')
    mod.levels = 2
  if  mirror_face != None:
    pivot = build_mirror_pivot(mirror_face,verts,ob)
    mirror = mods.new("mirror",'MIRROR')
    mirror.mirror_object = pivot
    mirror.use_clip = True
    mirror.use_mirror_merge = True
    #ob.parent = pivot

  if b'state' in props:
    state = props[b'state']
    if state == b'locked' or state == b'hidden_locked':
      ob.hide_select = True
    if state == b'hidden' or state == b'hidden_locked':
      ob.hide = True
      ob.hide_render = True
  if b'plugin_states' in props:
    plugin_states = props[b'plugin_states']
    if b'wings_shape' in plugin_states:
      folder = plugin_states[b'wings_shape']
      if folder != b'no_folder':
        dummy = bpy.data.objects.get(folder)
        if dummy == None:
          dummy = bpy.data.objects.new(folder,None)
          bpy.context.scene.objects.link(dummy)
        ob.parent = dummy
Exemplo n.º 3
0
def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname):
    '''
    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

    if unique_smooth_groups:
        sharp_edges = {}
        smooth_group_users = {context_smooth_group: {} for context_smooth_group in list(unique_smooth_groups.keys())}
        context_smooth_group_old = -1

    # Split fgons into tri's
    fgon_edges = {}  # Used for storing fgon keys
    if CREATE_EDGES:
        edges = []

    context_object = None

    # reverse loop through face indices
    for f_idx in range(len(faces) - 1, -1, -1):

        face_vert_loc_indices,\
        face_vert_tex_indices,\
        context_material,\
        context_smooth_group,\
        context_object = faces[f_idx]

        len_face_vert_loc_indices = len(face_vert_loc_indices)

        if len_face_vert_loc_indices == 1:
            faces.pop(f_idx)  # cant add single vert faces

        elif not face_vert_tex_indices or len_face_vert_loc_indices == 2:  # faces that have no texture coords are lines
            if CREATE_EDGES:
                # generators are better in python 2.4+ but can't be used in 2.3
                # edges.extend( (face_vert_loc_indices[i], face_vert_loc_indices[i+1]) for i in xrange(len_face_vert_loc_indices-1) )
                edges.extend([(face_vert_loc_indices[i], face_vert_loc_indices[i + 1]) for i in range(len_face_vert_loc_indices - 1)])

            faces.pop(f_idx)
        else:

            # Smooth Group
            if unique_smooth_groups and context_smooth_group:
                # Is a part of of a smooth group and is a face
                if context_smooth_group_old is not context_smooth_group:
                    edge_dict = smooth_group_users[context_smooth_group]
                    context_smooth_group_old = context_smooth_group

                for i in range(len_face_vert_loc_indices):
                    i1 = face_vert_loc_indices[i]
                    i2 = face_vert_loc_indices[i - 1]
                    if i1 > i2:
                        i1, i2 = i2, i1

                    try:
                        edge_dict[i1, i2] += 1
                    except KeyError:
                        edge_dict[i1, i2] = 1

            # FGons into triangles
            if has_ngons and len_face_vert_loc_indices > 4:

                ngon_face_indices = BPyMesh_ngon(verts_loc, face_vert_loc_indices)
                faces.extend(
                    [(
                    [face_vert_loc_indices[ngon[0]], face_vert_loc_indices[ngon[1]], face_vert_loc_indices[ngon[2]]],
                    [face_vert_tex_indices[ngon[0]], face_vert_tex_indices[ngon[1]], face_vert_tex_indices[ngon[2]]],
                    context_material,
                    context_smooth_group,
                    context_object)
                    for ngon in ngon_face_indices]
                )

                # edges to make fgons
                if CREATE_FGONS:
                    edge_users = {}
                    for ngon in ngon_face_indices:
                        for i in (0, 1, 2):
                            i1 = face_vert_loc_indices[ngon[i]]
                            i2 = face_vert_loc_indices[ngon[i - 1]]
                            if i1 > i2:
                                i1, i2 = i2, i1

                            try:
                                edge_users[i1, i2] += 1
                            except KeyError:
                                edge_users[i1, i2] = 1

                    for key, users in edge_users.items():
                        if users > 1:
                            fgon_edges[key] = None

                # remove all after 3, means we dont have to pop this one.
                faces.pop(f_idx)

    # Build sharp edges
    if unique_smooth_groups:
        for edge_dict in list(smooth_group_users.values()):
            for key, users in list(edge_dict.items()):
                if users == 1:  # This edge is on the boundry of a group
                    sharp_edges[key] = None

    # map the material names to an index
    material_mapping = {name: i for i, name in enumerate(unique_materials)}  # enumerate over unique_materials keys()

    materials = [None] * len(unique_materials)

    for name, index in list(material_mapping.items()):
        materials[index] = unique_materials[name]

    me = bpy.data.meshes.new(dataname.decode('utf-8', "replace"))

    # make sure the list isnt too big
    for material in materials:
        me.materials.append(material)

    me.vertices.add(len(verts_loc))
    me.faces.add(len(faces))

    # verts_loc is a list of (x, y, z) tuples
    me.vertices.foreach_set("co", unpack_list(verts_loc))

    # faces is a list of (vert_indices, texco_indices, ...) tuples
    # XXX faces should contain either 3 or 4 verts
    # XXX no check for valid face indices
    me.faces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces]))

    if verts_tex and me.faces:
        me.uv_textures.new()

    context_material_old = -1  # avoid a dict lookup
    mat = 0  # rare case it may be un-initialized.
    me_faces = me.faces

    for i, face in enumerate(faces):
        if len(face[0]) < 2:
            pass  # raise "bad face"
        elif len(face[0]) == 2:
            if CREATE_EDGES:
                edges.append(face[0])
        else:

                blender_face = me.faces[i]

                face_vert_loc_indices,\
                face_vert_tex_indices,\
                context_material,\
                context_smooth_group,\
                context_object = face

                if context_smooth_group:
                    blender_face.use_smooth = True

                if context_material:
                    if context_material_old is not context_material:
                        mat = material_mapping[context_material]
                        context_material_old = context_material

                    blender_face.material_index = mat
#                     blender_face.mat= mat

                if verts_tex:

                    blender_tface = me.uv_textures[0].data[i]

                    if context_material:
                        image, has_data = unique_material_images[context_material]
                        if image:  # Can be none if the material dosnt have an image.
                            blender_tface.image = image
                            blender_tface.use_image = True
                            if has_data and image.depth == 32:
                                blender_tface.blend_type = 'ALPHA'

                    # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled.
                    if len(face_vert_loc_indices) == 4:
                        if face_vert_loc_indices[2] == 0 or face_vert_loc_indices[3] == 0:
                            face_vert_tex_indices = face_vert_tex_indices[2], face_vert_tex_indices[3], face_vert_tex_indices[0], face_vert_tex_indices[1]
                    else:  # length of 3
                        if face_vert_loc_indices[2] == 0:
                            face_vert_tex_indices = face_vert_tex_indices[1], face_vert_tex_indices[2], face_vert_tex_indices[0]
                    # END EEEKADOODLE FIX

                    # assign material, uv's and image
                    blender_tface.uv1 = verts_tex[face_vert_tex_indices[0]]
                    blender_tface.uv2 = verts_tex[face_vert_tex_indices[1]]
                    blender_tface.uv3 = verts_tex[face_vert_tex_indices[2]]

                    if len(face_vert_loc_indices) == 4:
                        blender_tface.uv4 = verts_tex[face_vert_tex_indices[3]]

#                     for ii, uv in enumerate(blender_face.uv):
#                         uv.x, uv.y=  verts_tex[face_vert_tex_indices[ii]]
    del me_faces
#     del ALPHA

    if CREATE_EDGES and not edges:
        CREATE_EDGES = False

    if CREATE_EDGES:
        me.edges.add(len(edges))

        # edges should be a list of (a, b) tuples
        me.edges.foreach_set("vertices", unpack_list(edges))
#         me_edges.extend( edges )

#     del me_edges

    # Add edge faces.
#     me_edges= me.edges

    def edges_match(e1, e2):
        return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])

    # XXX slow
#     if CREATE_FGONS and fgon_edges:
#         for fgon_edge in fgon_edges.keys():
#             for ed in me.edges:
#                 if edges_match(fgon_edge, ed.vertices):
#                     ed.is_fgon = True

#     if CREATE_FGONS and fgon_edges:
#         FGON= Mesh.EdgeFlags.FGON
#         for ed in me.findEdges( fgon_edges.keys() ):
#             if ed is not None:
#                 me_edges[ed].flag |= FGON
#         del FGON

    # XXX slow
#     if unique_smooth_groups and sharp_edges:
#         for sharp_edge in sharp_edges.keys():
#             for ed in me.edges:
#                 if edges_match(sharp_edge, ed.vertices):
#                     ed.use_edge_sharp = True

#     if unique_smooth_groups and sharp_edges:
#         SHARP= Mesh.EdgeFlags.SHARP
#         for ed in me.findEdges( sharp_edges.keys() ):
#             if ed is not None:
#                 me_edges[ed].flag |= SHARP
#         del SHARP

    me.validate()
    me.update(calc_edges=CREATE_EDGES)

    ob = bpy.data.objects.new("Mesh", me)
    new_objects.append(ob)

    # Create the vertex groups. No need to have the flag passed here since we test for the
    # content of the vertex_groups. If the user selects to NOT have vertex groups saved then
    # the following test will never run
    for group_name, group_indices in vertex_groups.items():
        group = ob.vertex_groups.new(group_name)
        group.add(group_indices, 1.0, 'REPLACE')
Exemplo n.º 4
0
def read_shape(data, use_subsurf, use_hidden):
    read_tuple_header(data)
    skip_token(data)  #object
    shape_name = read_token(data)
    print("shape: ", shape_name)
    read_tuple_header(data)
    skip_token(data)  #winged

    #read mesh data
    edge_table = read_array(data, read_edge_set)
    print("edge_table: ", edge_table)
    face_props = read_array(data, read_array_as_dict)
    print("face_mats: ", face_props)
    verts = read_array(data, read_vertex_array)
    print("verts: ", verts)
    hard_edges = read_array(data)
    print("hard_edges: ", hard_edges)
    props = read_array_as_dict(data, read_prop)
    print("props: ", props)

    # if we are ignoring hidden objects
    # we can stop now
    if use_hidden == True and b'state' in props:
        state = props[b'state']
        if state == b'hidden' or state == b'hidden_locked':
            return

    # make a list of edges with just the vert part
    # of the list eg [(v0,v1),(v0,v1)...]
    edges = get_edges(edge_table)
    print("edges: ", edges)

    # build a list of faces from edge data,
    # also vertex colors, face_uvs and a few other bits
    # and pieces
    faces, face_cols, face_uvs, hide_edges, mirror_face = faces_from_edge_table(
        edge_table, verts, props, face_props, edges)
    print("edges: ", edges)
    print("faces: ", faces)
    print("colors: ", face_cols)
    print("uvs: ", face_uvs)
    print("hide edges: ", hide_edges)

    #create bleneder mesh
    me = bpy.data.meshes.new(shape_name)
    ob = bpy.data.objects.new(shape_name, me)
    bpy.context.scene.objects.link(ob)
    me.vertices.add(len(verts))
    me.vertices.foreach_set("co", unpack_list(verts))
    me.faces.add(len(faces))
    me.faces.foreach_set("vertices_raw", unpack_face_list(faces))
    me.edges.add(len(edges))
    me.edges.foreach_set("vertices", unpack_list(edges))
    me.validate()
    # me.update(calc_edges=True)

    #add edges to blender mesh, mark special edges
    #b_edges = me.edges
    #for i in range(len(b_edges)):
    #(v0,v1) = b_edges[i].vertices
    #print("edge ", i, " ",v0,"-",v1)

    build_hard_edges(me, hard_edges)
    hide_fgon_edges(me, hide_edges)

    if len(face_cols) > 0: build_face_colors(me, face_cols)
    if len(face_uvs) > 0: build_face_uvs(me, face_uvs)
    for i in range(len(faces)):
        me.faces[i].use_smooth = True
    add_material_indices(me, face_props)

    mods = ob.modifiers
    if use_subsurf == True:
        mod = mods.new("subsurf", 'SUBSURF')
        mod.levels = 2
    if mirror_face != None:
        pivot = build_mirror_pivot(mirror_face, verts, ob)
        mirror = mods.new("mirror", 'MIRROR')
        mirror.mirror_object = pivot
        mirror.use_clip = True
        mirror.use_mirror_merge = True
        #ob.parent = pivot

    if b'state' in props:
        state = props[b'state']
        if state == b'locked' or state == b'hidden_locked':
            ob.hide_select = True
        if state == b'hidden' or state == b'hidden_locked':
            ob.hide = True
            ob.hide_render = True
    if b'plugin_states' in props:
        plugin_states = props[b'plugin_states']
        if b'wings_shape' in plugin_states:
            folder = plugin_states[b'wings_shape']
            if folder != b'no_folder':
                dummy = bpy.data.objects.get(folder)
                if dummy == None:
                    dummy = bpy.data.objects.new(folder, None)
                    bpy.context.scene.objects.link(dummy)
                ob.parent = dummy
Exemplo n.º 5
0
def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, vertex_groups, dataname):
    '''
    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

    if unique_smooth_groups:
        sharp_edges = {}
        smooth_group_users = {context_smooth_group: {} for context_smooth_group in list(unique_smooth_groups.keys())}
        context_smooth_group_old = -1

    # Split fgons into tri's
    fgon_edges = {}  # Used for storing fgon keys
    if CREATE_EDGES:
        edges = []

    context_object = None

    # reverse loop through face indices
    for f_idx in range(len(faces) - 1, -1, -1):

        face_vert_loc_indices,\
        face_vert_tex_indices,\
        context_material,\
        context_smooth_group,\
        context_object = faces[f_idx]

        len_face_vert_loc_indices = len(face_vert_loc_indices)

        if len_face_vert_loc_indices == 1:
            faces.pop(f_idx)  # cant add single vert faces

        elif not face_vert_tex_indices or len_face_vert_loc_indices == 2:  # faces that have no texture coords are lines
            if CREATE_EDGES:
                # generators are better in python 2.4+ but can't be used in 2.3
                # edges.extend( (face_vert_loc_indices[i], face_vert_loc_indices[i+1]) for i in xrange(len_face_vert_loc_indices-1) )
                edges.extend([(face_vert_loc_indices[i], face_vert_loc_indices[i + 1]) for i in range(len_face_vert_loc_indices - 1)])

            faces.pop(f_idx)
        else:

            # Smooth Group
            if unique_smooth_groups and context_smooth_group:
                # Is a part of of a smooth group and is a face
                if context_smooth_group_old is not context_smooth_group:
                    edge_dict = smooth_group_users[context_smooth_group]
                    context_smooth_group_old = context_smooth_group

                for i in range(len_face_vert_loc_indices):
                    i1 = face_vert_loc_indices[i]
                    i2 = face_vert_loc_indices[i - 1]
                    if i1 > i2:
                        i1, i2 = i2, i1

                    try:
                        edge_dict[i1, i2] += 1
                    except KeyError:
                        edge_dict[i1, i2] = 1

            # FGons into triangles
            if has_ngons and len_face_vert_loc_indices > 4:

                ngon_face_indices = BPyMesh_ngon(verts_loc, face_vert_loc_indices)
                faces.extend(
                    [(
                    [face_vert_loc_indices[ngon[0]], face_vert_loc_indices[ngon[1]], face_vert_loc_indices[ngon[2]]],
                    [face_vert_tex_indices[ngon[0]], face_vert_tex_indices[ngon[1]], face_vert_tex_indices[ngon[2]]],
                    context_material,
                    context_smooth_group,
                    context_object)
                    for ngon in ngon_face_indices]
                )

                # edges to make fgons
                if CREATE_FGONS:
                    edge_users = {}
                    for ngon in ngon_face_indices:
                        for i in (0, 1, 2):
                            i1 = face_vert_loc_indices[ngon[i]]
                            i2 = face_vert_loc_indices[ngon[i - 1]]
                            if i1 > i2:
                                i1, i2 = i2, i1

                            try:
                                edge_users[i1, i2] += 1
                            except KeyError:
                                edge_users[i1, i2] = 1

                    for key, users in edge_users.items():
                        if users > 1:
                            fgon_edges[key] = None

                # remove all after 3, means we dont have to pop this one.
                faces.pop(f_idx)

    # Build sharp edges
    if unique_smooth_groups:
        for edge_dict in list(smooth_group_users.values()):
            for key, users in list(edge_dict.items()):
                if users == 1:  # This edge is on the boundry of a group
                    sharp_edges[key] = None

    # map the material names to an index
    material_mapping = {name: i for i, name in enumerate(unique_materials)}  # enumerate over unique_materials keys()

    materials = [None] * len(unique_materials)

    for name, index in list(material_mapping.items()):
        materials[index] = unique_materials[name]

    me = bpy.data.meshes.new(dataname.decode('utf-8', "replace"))

    # make sure the list isnt too big
    for material in materials:
        me.materials.append(material)

    me.vertices.add(len(verts_loc))
    me.faces.add(len(faces))

    # verts_loc is a list of (x, y, z) tuples
    me.vertices.foreach_set("co", unpack_list(verts_loc))

    # faces is a list of (vert_indices, texco_indices, ...) tuples
    # XXX faces should contain either 3 or 4 verts
    # XXX no check for valid face indices
    me.faces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces]))

    if verts_tex and me.faces:
        me.uv_textures.new()

    context_material_old = -1  # avoid a dict lookup
    mat = 0  # rare case it may be un-initialized.
    me_faces = me.faces

    for i, face in enumerate(faces):
        if len(face[0]) < 2:
            pass  # raise "bad face"
        elif len(face[0]) == 2:
            if CREATE_EDGES:
                edges.append(face[0])
        else:

                blender_face = me.faces[i]

                face_vert_loc_indices,\
                face_vert_tex_indices,\
                context_material,\
                context_smooth_group,\
                context_object = face

                if context_smooth_group:
                    blender_face.use_smooth = True

                if context_material:
                    if context_material_old is not context_material:
                        mat = material_mapping[context_material]
                        context_material_old = context_material

                    blender_face.material_index = mat
#                     blender_face.mat= mat

                if verts_tex:

                    blender_tface = me.uv_textures[0].data[i]

                    if context_material:
                        image, has_data = unique_material_images[context_material]
                        if image:  # Can be none if the material dosnt have an image.
                            blender_tface.image = image
                            blender_tface.use_image = True
                            if has_data and image.depth == 32:
                                blender_tface.blend_type = 'ALPHA'

                    # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled.
                    if len(face_vert_loc_indices) == 4:
                        if face_vert_loc_indices[2] == 0 or face_vert_loc_indices[3] == 0:
                            face_vert_tex_indices = face_vert_tex_indices[2], face_vert_tex_indices[3], face_vert_tex_indices[0], face_vert_tex_indices[1]
                    else:  # length of 3
                        if face_vert_loc_indices[2] == 0:
                            face_vert_tex_indices = face_vert_tex_indices[1], face_vert_tex_indices[2], face_vert_tex_indices[0]
                    # END EEEKADOODLE FIX

                    # assign material, uv's and image
                    blender_tface.uv1 = verts_tex[face_vert_tex_indices[0]]
                    blender_tface.uv2 = verts_tex[face_vert_tex_indices[1]]
                    blender_tface.uv3 = verts_tex[face_vert_tex_indices[2]]

                    if len(face_vert_loc_indices) == 4:
                        blender_tface.uv4 = verts_tex[face_vert_tex_indices[3]]

#                     for ii, uv in enumerate(blender_face.uv):
#                         uv.x, uv.y=  verts_tex[face_vert_tex_indices[ii]]
    del me_faces
#     del ALPHA

    if CREATE_EDGES and not edges:
        CREATE_EDGES = False

    if CREATE_EDGES:
        me.edges.add(len(edges))

        # edges should be a list of (a, b) tuples
        me.edges.foreach_set("vertices", unpack_list(edges))
#         me_edges.extend( edges )

#     del me_edges

    # Add edge faces.
#     me_edges= me.edges

    def edges_match(e1, e2):
        return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])

    # XXX slow
#     if CREATE_FGONS and fgon_edges:
#         for fgon_edge in fgon_edges.keys():
#             for ed in me.edges:
#                 if edges_match(fgon_edge, ed.vertices):
#                     ed.is_fgon = True

#     if CREATE_FGONS and fgon_edges:
#         FGON= Mesh.EdgeFlags.FGON
#         for ed in me.findEdges( fgon_edges.keys() ):
#             if ed is not None:
#                 me_edges[ed].flag |= FGON
#         del FGON

    # XXX slow
#     if unique_smooth_groups and sharp_edges:
#         for sharp_edge in sharp_edges.keys():
#             for ed in me.edges:
#                 if edges_match(sharp_edge, ed.vertices):
#                     ed.use_edge_sharp = True

#     if unique_smooth_groups and sharp_edges:
#         SHARP= Mesh.EdgeFlags.SHARP
#         for ed in me.findEdges( sharp_edges.keys() ):
#             if ed is not None:
#                 me_edges[ed].flag |= SHARP
#         del SHARP

    me.update(calc_edges=CREATE_EDGES)
#     me.calcNormals()

    ob = bpy.data.objects.new("Mesh", me)
    new_objects.append(ob)

    # Create the vertex groups. No need to have the flag passed here since we test for the
    # content of the vertex_groups. If the user selects to NOT have vertex groups saved then
    # the following test will never run
    for group_name, group_indices in vertex_groups.items():
        group = ob.vertex_groups.new(group_name)
        group.add(group_indices, 1.0, 'REPLACE')