예제 #1
0
def bm_make_uv_layer(pim_version, bm, faces, uv_layer_name, uv_layer_data):
    """Add UV Layer to the BMesh object.

    :param pim_version: PIM version of the File from which data have been read
    :type pim_version: int
    :param bm: BMesh data to add UV Layer to
    :type bm: bmesh.types.BMesh
    :param faces: Faces as Vertex indices
    :type faces: list
    :param uv_layer_name: Name for the layer
    :type uv_layer_name: str
    :param uv_layer_data: UV Layer data
    :type uv_layer_data: list
    """
    uv_lay = bm.loops.layers.uv.new(uv_layer_name)
    for face_i, face in enumerate(bm.faces):
        # f_v = shift_values(faces[face_i])  # NOTE: Needed for Blender versions prior 2.69 (Blender bug)
        f_v = faces[face_i]  # NOTE: For Blender 2.69 and above
        # print('   face[%i]: %s / %s' % (face_i, str(face), str(f_v)))
        # print_values(" * f_verts", f_v, 10)
        for loop_i, loop in enumerate(face.loops):
            if pim_version < 6:
                loop[uv_lay].uv = _convert.change_to_scs_uv_coordinates(
                    uv_layer_data[f_v[loop_i]])
            else:
                loop[uv_lay].uv = _convert.change_to_scs_uv_coordinates(
                    uv_layer_data[face_i][loop_i])
예제 #2
0
def bm_make_uv_layer(pim_version, bm, faces, uv_layer_name, uv_layer_data):
    """Add UV Layer to the BMesh object.

    :param pim_version: PIM version of the File from which data have been read
    :type pim_version: int
    :param bm: BMesh data to add UV Layer to
    :type bm: bmesh.types.BMesh
    :param faces: Faces as Vertex indices
    :type faces: list
    :param uv_layer_name: Name for the layer
    :type uv_layer_name: str
    :param uv_layer_data: UV Layer data
    :type uv_layer_data: list
    """
    uv_lay = bm.loops.layers.uv.new(uv_layer_name)
    for face_i, face in enumerate(bm.faces):
        # f_v = shift_values(faces[face_i])  # NOTE: Needed for Blender versions prior 2.69 (Blender bug)
        f_v = faces[face_i]  # NOTE: For Blender 2.69 and above
        # print('   face[%i]: %s / %s' % (face_i, str(face), str(f_v)))
        # print_values(" * f_verts", f_v, 10)
        for loop_i, loop in enumerate(face.loops):
            if pim_version < 6:
                loop[uv_lay].uv = _convert.change_to_scs_uv_coordinates(uv_layer_data[f_v[loop_i]])
            else:
                loop[uv_lay].uv = _convert.change_to_scs_uv_coordinates(uv_layer_data[face_i][loop_i])
예제 #3
0
def _get_geometry_dict(root_object, obj, mesh, offset_matrix, material_dict,
                       used_materials, bone_list, scs_globals):
    """
    :param root_object: SCS Root Object
    :type root_object: bpy.types.Object
    :param obj: Actual Object data
    :type obj: bpy.types.Object
    :param mesh: Object's Mesh data
    :type mesh: bpy.types.Mesh
    :param offset_matrix: Matrix for specifying of pivot point
    :type offset_matrix: Matrix
    :param material_dict: Materials used in current Object
    :type material_dict: dict
    :param used_materials: All Materials used in 'SCS Game Object'
    :type used_materials: list
    :param bone_list: Bones for export
    :type bone_list: list
    :param scs_globals: SCS Tools Globals
    :type scs_globals: GlobalSCSProps
    :return: Piece dictionary, Skin list, Skin weight count, Skin clone count
    :rtype: list
    """
    # Create Index => Material Dictionary...
    index_material_dict = _create_index_material_dict(material_dict)

    # Create Piece (Material) Dictionary...
    piece_dict = {}
    for material in material_dict:
        material_i = loc_material_i = material_dict[material][
            0]  # Eliminates multiple Material assignment

        # Set correct Material index for Piece
        for used_mat_i, used_mat in enumerate(used_materials):
            if material == used_mat:
                material_i = used_mat_i

        # print(' "%s" = %s => %s' % (str(material), str(material_dict[material]), str(loc_material_i)))

        piece_dict[loc_material_i] = {}
        piece_dict[loc_material_i]['material_index'] = material_i
        piece_dict[loc_material_i]['hash_dict'] = {}
        piece_dict[loc_material_i]['verts'] = []
        piece_dict[loc_material_i]['faces'] = []

    # DATA LAYERS
    uv_layers = mesh.tessface_uv_textures
    vc_layers = mesh.tessface_vertex_colors
    vertex_groups = obj.vertex_groups

    # Make sure if everything is recalculated...
    mesh.calc_tessface()
    mesh.calc_normals()
    mesh.calc_normals_split()

    for tessface in mesh.tessfaces:
        material = index_material_dict[tessface.material_index]
        loc_material_i = material_dict[material][
            0]  # Eliminates multiple Material assignment
        # print('tessface [%s]: %s' % (str(tessface.index).rjust(2, "0"), str(tessface.vertices)))
        # print(' "%s" = %s => %s' % (str(material), str(material_dict[material]), str(material_i)))
        face_verts = []

        for facevert_i, facevert in enumerate(tessface.vertices):
            facevert_common_data = {}
            facevert_unique_data = {}
            # POSITION
            facevert_co = offset_matrix.inverted(
            ) * obj.matrix_world * mesh.vertices[facevert].co
            # print('  facevert [%s] - position: %s' % (str(facevert).rjust(2, "0"), str(facevert_co)))
            scs_position = (Matrix.Scale(scs_globals.export_scale, 4) *
                            _convert_utils.scs_to_blend_matrix().inverted() *
                            facevert_co)
            facevert_common_data['_POSITION'] = scs_position

            # NORMAL
            facevert_no = mesh.vertices[facevert].normal
            # print('    normal: %s' % str(facevert_no))
            scs_normal = (_convert_utils.scs_to_blend_matrix().inverted() *
                          offset_matrix.inverted() * obj.matrix_world *
                          facevert_no)

            # normalize normal vector and set it
            facevert_common_data['_NORMAL'] = Vector(scs_normal).normalized()

            # VERTEX GROUPS - for every vertices we need weight for every existing vertex group
            # print('    vg : %s len(%i)' % (str(vertex_groups), len(vertex_groups)))
            vert_grp = {}
            unused_groups = vertex_groups.keys(
            )  # store all groups that are not yet used
            for vg_elem in mesh.vertices[facevert].groups:
                vert_grp[vertex_groups[vg_elem.group].name] = vg_elem.weight
                unused_groups.remove(
                    vertex_groups[vg_elem.group].name)  # remove it from unused
            for group_name in unused_groups:  # for all unused groups that are left write weight 0
                vert_grp[group_name] = 0.0

            # print('      vert_grp: %s' % str(vert_grp))
            facevert_common_data['_VG'] = vert_grp

            # VERTEX UV LAYERS
            # print('    uv: %s len(%i)' % (str(uv_layers), len(uv_layers)))
            uv_lyr = {}
            if scs_globals.active_uv_only:
                uv = uv_layers.active.data[tessface.index].uv[facevert_i][:]
                scs_uv = _convert_utils.change_to_scs_uv_coordinates(uv)
                uv_lyr[uv_layers.active.name] = Vector(scs_uv)
            else:
                for layer_i, layer in enumerate(uv_layers.keys()):
                    uv = uv_layers[layer_i].data[
                        tessface.index].uv[facevert_i][:]
                    # print('      uv%i: %r %s' % (layer_i, layer, str(uv)))
                    scs_uv = _convert_utils.change_to_scs_uv_coordinates(uv)
                    uv_lyr[layer] = Vector(scs_uv)
            # print('      uv_lyr: %s' % str(uv_lyr))
            facevert_unique_data['_UV'] = uv_lyr

            # VERTEX COLOR LAYERS
            # NOTE: In current PIM version 5 there should be only one Color layer present,
            # but I'll leave the multilayer solution here just for the case it could
            # be used in the future.
            active_vc_only = True
            # print('    vc : %s len(%i)' % (str(vc_layers), len(vc_layers)))
            if vc_layers and scs_globals.export_vertex_color:
                vc_lyr = {}
                if active_vc_only:
                    if facevert_i == 0:
                        vc = vc_layers.active.data[tessface.index].color1[:]
                    elif facevert_i == 1:
                        vc = vc_layers.active.data[tessface.index].color2[:]
                    elif facevert_i == 2:
                        vc = vc_layers.active.data[tessface.index].color3[:]
                    elif facevert_i == 3:
                        vc = vc_layers.active.data[tessface.index].color4[:]
                    if scs_globals.export_vertex_color_type == 'rgbda':
                        vc = (vc[0], vc[1], vc[2], 1.0)
                    # print('      vc%i: %r %s' % (layer_i, layer, str(vc)))
                    vc_lyr[vc_layers.active.name] = Vector(vc)
                else:
                    for layer_i, layer in enumerate(vc_layers.keys()):
                        if facevert_i == 0:
                            vc = vc_layers[layer_i].data[
                                tessface.index].color1[:]
                        elif facevert_i == 1:
                            vc = vc_layers[layer_i].data[
                                tessface.index].color2[:]
                        elif facevert_i == 2:
                            vc = vc_layers[layer_i].data[
                                tessface.index].color3[:]
                        elif facevert_i == 3:
                            vc = vc_layers[layer_i].data[
                                tessface.index].color4[:]
                        if scs_globals.export_vertex_color_type == 'rgbda':
                            vc = (vc[0], vc[1], vc[2], 1.0)
                        # print('      vc%i: %r %s' % (layer_i, layer, str(vc)))
                        vc_lyr[layer] = Vector(vc)
                # print('      vc_lyr: %s' % str(vc_lyr))
                facevert_unique_data['_RGBA'] = vc_lyr

            # DATA EVALUATION
            # print(' *** (%s) *** (%s) ***' % (str(facevert).rjust(3, "0"), str(tessface.vertices[facevert_i]).rjust(3, "0")))
            if facevert in piece_dict[loc_material_i]['hash_dict']:
                for vert in piece_dict[loc_material_i]['hash_dict'][facevert]:
                    # print(' %s > UD: %s' % (str(facevert).rjust(3, "0"), str(facevert_unique_data)))
                    vert_facevert_unique_data = piece_dict[loc_material_i][
                        'verts'][vert][1]
                    # print(' %s < UD: %s' % (str(facevert).rjust(3, "0"), str(vert_facevert_unique_data)))
                    if facevert_unique_data == vert_facevert_unique_data:
                        # print(' %s O MATCH!' % str(facevert).rjust(3, "0"))
                        face_verts.append(vert)
                        break
                else:
                    # print(' %s - NOT in existing record...' % str(facevert).rjust(3, "0"))
                    new_vert_index = len(piece_dict[loc_material_i]['verts'])
                    piece_dict[loc_material_i]['hash_dict'][facevert].append(
                        new_vert_index
                    )  # Add the new vertex index to "hash_dict" record
                    face_verts.append(
                        new_vert_index)  # Add the vertex to the actual face
                    piece_dict[loc_material_i]['verts'].append(
                        (facevert_common_data, facevert_unique_data
                         ))  # Create a new vertex to 'verts'
            else:
                # print(' %s | NOT a record... %s' % (str(facevert).rjust(3, "0"), str(facevert_common_data['_POSITION'][:])))
                new_vert_index = len(piece_dict[loc_material_i]['verts'])
                piece_dict[loc_material_i]['hash_dict'][facevert] = [
                    new_vert_index
                ]  # Create a new "hash_dict" record
                face_verts.append(
                    new_vert_index)  # Add vertex to the actual face
                piece_dict[loc_material_i]['verts'].append(
                    (facevert_common_data,
                     facevert_unique_data))  # Create a new vertex to 'verts'

        # FACES
        face_verts = face_verts[::
                                -1]  # NOTE: Vertex order is swapped here to make the face normal flipped! Needs a check if it is right.
        if len(face_verts) == 4:  # Simple triangulation...
            piece_dict[loc_material_i]['faces'].append(face_verts[:3])
            piece_dict[loc_material_i]['faces'].append(
                (face_verts[2], face_verts[3], face_verts[0]))
        else:
            piece_dict[loc_material_i]['faces'].append(face_verts)

    # BONE NAME LIST
    skin_list = []
    skin_weights_cnt = skin_clones_cnt = 0
    if bone_list:
        # if _get_scs_globals().export_anim_file == 'anim':
        if root_object.scs_props.scs_root_animated == 'anim':
            bone_name_list = []
            for bone_i, bone in enumerate(bone_list):
                bone_name_list.append(bone.name)
                # print('%s bone: %r' % (str(bone_i).rjust(3, "0"), str(bone.name)))

            # SKINNING DATA
            for vert in mesh.vertices:

                # SKIN VECTOR
                # position = Vector(mesh.vertices[vert_i].co)
                scs_position = (
                    Matrix.Scale(scs_globals.export_scale, 4) *
                    _convert_utils.scs_to_blend_matrix().inverted() *
                    obj.matrix_world * vert.co)
                # NOTE: Vertex position - when exported from Maya the value get scaled *10, but it is old & unused in game engine anyway.
                skin_vector = scs_position
                # print('    vertex: %s: %s' % (str(vert.index), str(piece_dict[material_i]['hash_dict'][vert.index])))

                # SKIN WEIGHTS
                skin_weights = []
                for vg_elem in vert.groups:
                    group_name = vertex_groups[vg_elem.group].name
                    if group_name in bone_name_list:
                        # print('      group: %r - %s' % (group_name, str(group.weight)))
                        bone_index = _get_vertex_group_index(
                            bone_name_list, group_name)
                        skin_weights.append((bone_index, vg_elem.weight))
                        skin_weights_cnt += 1
                    else:
                        print(
                            'WARNING - Vertex Group %r is not a bone weight...'
                            % group_name
                        )  # TODO: Maybe handle this case? Useful?
                skin_clones = []

                # SKIN CLONES
                if loc_material_i is not None:
                    for v in piece_dict[loc_material_i]['hash_dict'][
                            vert.index]:
                        skin_clones.append((0, v))
                        skin_clones_cnt += 1
                else:
                    print(
                        'ERROR - Material indices incorrect! (get_geometry_dict())'
                    )

                skin_list.append((skin_vector, skin_weights, skin_clones))

    mesh.free_normals_split()

    # print(' ** piece_dict: %s' % str(piece_dict))
    # print('')

    return piece_dict, skin_list, skin_weights_cnt, skin_clones_cnt
예제 #4
0
def _get_geometry_dict(root_object, obj, mesh, offset_matrix, material_dict, used_materials, bone_list, scs_globals):
    """
    :param root_object: SCS Root Object
    :type root_object: bpy.types.Object
    :param obj: Actual Object data
    :type obj: bpy.types.Object
    :param mesh: Object's Mesh data
    :type mesh: bpy.types.Mesh
    :param offset_matrix: Matrix for specifying of pivot point
    :type offset_matrix: Matrix
    :param material_dict: Materials used in current Object
    :type material_dict: dict
    :param used_materials: All Materials used in 'SCS Game Object'
    :type used_materials: list
    :param bone_list: Bones for export
    :type bone_list: list
    :param scs_globals: SCS Tools Globals
    :type scs_globals: GlobalSCSProps
    :return: Piece dictionary, Skin list, Skin weight count, Skin clone count
    :rtype: list
    """
    # Create Index => Material Dictionary...
    index_material_dict = _create_index_material_dict(material_dict)

    # Create Piece (Material) Dictionary...
    piece_dict = {}
    for material in material_dict:
        material_i = loc_material_i = material_dict[material][0]  # Eliminates multiple Material assignment

        # Set correct Material index for Piece
        for used_mat_i, used_mat in enumerate(used_materials):
            if material == used_mat:
                material_i = used_mat_i

        # print(' "%s" = %s => %s' % (str(material), str(material_dict[material]), str(loc_material_i)))

        piece_dict[loc_material_i] = {}
        piece_dict[loc_material_i]['material_index'] = material_i
        piece_dict[loc_material_i]['hash_dict'] = {}
        piece_dict[loc_material_i]['verts'] = []
        piece_dict[loc_material_i]['faces'] = []

    # DATA LAYERS
    uv_layers = mesh.tessface_uv_textures
    vc_layers = mesh.tessface_vertex_colors
    vertex_groups = obj.vertex_groups

    # Make sure if everything is recalculated...
    mesh.calc_tessface()
    mesh.calc_normals()
    mesh.calc_normals_split()

    for tessface in mesh.tessfaces:
        material = index_material_dict[tessface.material_index]
        loc_material_i = material_dict[material][0]  # Eliminates multiple Material assignment
        # print('tessface [%s]: %s' % (str(tessface.index).rjust(2, "0"), str(tessface.vertices)))
        # print(' "%s" = %s => %s' % (str(material), str(material_dict[material]), str(material_i)))
        face_verts = []

        for facevert_i, facevert in enumerate(tessface.vertices):
            facevert_common_data = {}
            facevert_unique_data = {}
            # POSITION
            facevert_co = offset_matrix.inverted() * obj.matrix_world * mesh.vertices[facevert].co
            # print('  facevert [%s] - position: %s' % (str(facevert).rjust(2, "0"), str(facevert_co)))
            scs_position = (Matrix.Scale(scs_globals.export_scale, 4) *
                            _convert_utils.scs_to_blend_matrix().inverted() *
                            facevert_co)
            facevert_common_data['_POSITION'] = scs_position

            # NORMAL
            facevert_no = mesh.vertices[facevert].normal
            # print('    normal: %s' % str(facevert_no))
            scs_normal = (_convert_utils.scs_to_blend_matrix().inverted() *
                          offset_matrix.inverted() *
                          obj.matrix_world *
                          facevert_no)

            # normalize normal vector and set it
            facevert_common_data['_NORMAL'] = Vector(scs_normal).normalized()

            # VERTEX GROUPS - for every vertices we need weight for every existing vertex group
            # print('    vg : %s len(%i)' % (str(vertex_groups), len(vertex_groups)))
            vert_grp = {}
            unused_groups = vertex_groups.keys()  # store all groups that are not yet used
            for vg_elem in mesh.vertices[facevert].groups:
                vert_grp[vertex_groups[vg_elem.group].name] = vg_elem.weight
                unused_groups.remove(vertex_groups[vg_elem.group].name)  # remove it from unused
            for group_name in unused_groups:  # for all unused groups that are left write weight 0
                vert_grp[group_name] = 0.0

            # print('      vert_grp: %s' % str(vert_grp))
            facevert_common_data['_VG'] = vert_grp

            # VERTEX UV LAYERS
            # print('    uv: %s len(%i)' % (str(uv_layers), len(uv_layers)))
            uv_lyr = {}
            if scs_globals.active_uv_only:
                uv = uv_layers.active.data[tessface.index].uv[facevert_i][:]
                scs_uv = _convert_utils.change_to_scs_uv_coordinates(uv)
                uv_lyr[uv_layers.active.name] = Vector(scs_uv)
            else:
                for layer_i, layer in enumerate(uv_layers.keys()):
                    uv = uv_layers[layer_i].data[tessface.index].uv[facevert_i][:]
                    # print('      uv%i: %r %s' % (layer_i, layer, str(uv)))
                    scs_uv = _convert_utils.change_to_scs_uv_coordinates(uv)
                    uv_lyr[layer] = Vector(scs_uv)
            # print('      uv_lyr: %s' % str(uv_lyr))
            facevert_unique_data['_UV'] = uv_lyr

            # VERTEX COLOR LAYERS
            # NOTE: In current PIM version 5 there should be only one Color layer present,
            # but I'll leave the multilayer solution here just for the case it could
            # be used in the future.
            active_vc_only = True
            # print('    vc : %s len(%i)' % (str(vc_layers), len(vc_layers)))
            if vc_layers and scs_globals.export_vertex_color:
                vc_lyr = {}
                if active_vc_only:
                    if facevert_i == 0:
                        vc = vc_layers.active.data[tessface.index].color1[:]
                    elif facevert_i == 1:
                        vc = vc_layers.active.data[tessface.index].color2[:]
                    elif facevert_i == 2:
                        vc = vc_layers.active.data[tessface.index].color3[:]
                    elif facevert_i == 3:
                        vc = vc_layers.active.data[tessface.index].color4[:]
                    if scs_globals.export_vertex_color_type == 'rgbda':
                        vc = (vc[0], vc[1], vc[2], 1.0)
                    # print('      vc%i: %r %s' % (layer_i, layer, str(vc)))
                    vc_lyr[vc_layers.active.name] = Vector(vc)
                else:
                    for layer_i, layer in enumerate(vc_layers.keys()):
                        if facevert_i == 0:
                            vc = vc_layers[layer_i].data[tessface.index].color1[:]
                        elif facevert_i == 1:
                            vc = vc_layers[layer_i].data[tessface.index].color2[:]
                        elif facevert_i == 2:
                            vc = vc_layers[layer_i].data[tessface.index].color3[:]
                        elif facevert_i == 3:
                            vc = vc_layers[layer_i].data[tessface.index].color4[:]
                        if scs_globals.export_vertex_color_type == 'rgbda':
                            vc = (vc[0], vc[1], vc[2], 1.0)
                        # print('      vc%i: %r %s' % (layer_i, layer, str(vc)))
                        vc_lyr[layer] = Vector(vc)
                # print('      vc_lyr: %s' % str(vc_lyr))
                facevert_unique_data['_RGBA'] = vc_lyr

            # DATA EVALUATION
            # print(' *** (%s) *** (%s) ***' % (str(facevert).rjust(3, "0"), str(tessface.vertices[facevert_i]).rjust(3, "0")))
            if facevert in piece_dict[loc_material_i]['hash_dict']:
                for vert in piece_dict[loc_material_i]['hash_dict'][facevert]:
                    # print(' %s > UD: %s' % (str(facevert).rjust(3, "0"), str(facevert_unique_data)))
                    vert_facevert_unique_data = piece_dict[loc_material_i]['verts'][vert][1]
                    # print(' %s < UD: %s' % (str(facevert).rjust(3, "0"), str(vert_facevert_unique_data)))
                    if facevert_unique_data == vert_facevert_unique_data:
                        # print(' %s O MATCH!' % str(facevert).rjust(3, "0"))
                        face_verts.append(vert)
                        break
                else:
                    # print(' %s - NOT in existing record...' % str(facevert).rjust(3, "0"))
                    new_vert_index = len(piece_dict[loc_material_i]['verts'])
                    piece_dict[loc_material_i]['hash_dict'][facevert].append(new_vert_index)  # Add the new vertex index to "hash_dict" record
                    face_verts.append(new_vert_index)  # Add the vertex to the actual face
                    piece_dict[loc_material_i]['verts'].append((facevert_common_data, facevert_unique_data))  # Create a new vertex to 'verts'
            else:
                # print(' %s | NOT a record... %s' % (str(facevert).rjust(3, "0"), str(facevert_common_data['_POSITION'][:])))
                new_vert_index = len(piece_dict[loc_material_i]['verts'])
                piece_dict[loc_material_i]['hash_dict'][facevert] = [new_vert_index]  # Create a new "hash_dict" record
                face_verts.append(new_vert_index)  # Add vertex to the actual face
                piece_dict[loc_material_i]['verts'].append((facevert_common_data, facevert_unique_data))  # Create a new vertex to 'verts'

        # FACES
        face_verts = face_verts[::-1]  # NOTE: Vertex order is swapped here to make the face normal flipped! Needs a check if it is right.
        if len(face_verts) == 4:  # Simple triangulation...
            piece_dict[loc_material_i]['faces'].append(face_verts[:3])
            piece_dict[loc_material_i]['faces'].append((face_verts[2], face_verts[3], face_verts[0]))
        else:
            piece_dict[loc_material_i]['faces'].append(face_verts)

    # BONE NAME LIST
    skin_list = []
    skin_weights_cnt = skin_clones_cnt = 0
    if bone_list:
        # if _get_scs_globals().export_anim_file == 'anim':
        if root_object.scs_props.scs_root_animated == 'anim':
            bone_name_list = []
            for bone_i, bone in enumerate(bone_list):
                bone_name_list.append(bone.name)
                # print('%s bone: %r' % (str(bone_i).rjust(3, "0"), str(bone.name)))

            # SKINNING DATA
            for vert in mesh.vertices:

                # SKIN VECTOR
                # position = Vector(mesh.vertices[vert_i].co)
                scs_position = (Matrix.Scale(scs_globals.export_scale, 4) *
                                _convert_utils.scs_to_blend_matrix().inverted() *
                                obj.matrix_world *
                                vert.co)
                # NOTE: Vertex position - when exported from Maya the value get scaled *10, but it is old & unused in game engine anyway.
                skin_vector = scs_position
                # print('    vertex: %s: %s' % (str(vert.index), str(piece_dict[material_i]['hash_dict'][vert.index])))

                # SKIN WEIGHTS
                skin_weights = []
                for vg_elem in vert.groups:
                    group_name = vertex_groups[vg_elem.group].name
                    if group_name in bone_name_list:
                        # print('      group: %r - %s' % (group_name, str(group.weight)))
                        bone_index = _get_vertex_group_index(bone_name_list, group_name)
                        skin_weights.append((bone_index, vg_elem.weight))
                        skin_weights_cnt += 1
                    else:
                        print('WARNING - Vertex Group %r is not a bone weight...' % group_name)  # TODO: Maybe handle this case? Useful?
                skin_clones = []

                # SKIN CLONES
                if loc_material_i is not None:
                    for v in piece_dict[loc_material_i]['hash_dict'][vert.index]:
                        skin_clones.append((0, v))
                        skin_clones_cnt += 1
                else:
                    print('ERROR - Material indices incorrect! (get_geometry_dict())')

                skin_list.append((skin_vector, skin_weights, skin_clones))

    mesh.free_normals_split()

    # print(' ** piece_dict: %s' % str(piece_dict))
    # print('')

    return piece_dict, skin_list, skin_weights_cnt, skin_clones_cnt