Example #1
0
def load(context, filepath, name_suffix="", suppress_reports=False):
    """

    :param context: Blender Context currently used for window_manager.update_progress and bpy_object_utils.object_data_add
    :type context: bpy.types.Context
    :param filepath: File path to be imported
    :type filepath: str
    :param name_suffix: files name suffix (exchange format is using .ef)
    :type name_suffix: str
    :param suppress_reports: True if you don't want for reports to be flushed & summaries to be printed out; False otherwise
    :type suppress_reports: bool
    :return: Return state statuses (Usually 'FINISHED')
    :rtype: set
    """
    import time

    t = time.time()
    bpy.context.window.cursor_modal_set('WAIT')
    scs_globals = _get_scs_globals()

    if not suppress_reports:
        lprint("", report_errors=-1, report_warnings=-1
               )  # Clear the 'error_messages' and 'warning_messages'

    collision_locators = []
    prefab_locators = []
    loaded_variants = []
    loaded_looks = []
    objects = []
    locators = []
    mats_info = []
    scs_root_object = skeleton = bones = armature = None

    # TRANSITIONAL STRUCTURES
    terrain_points = TerrainPntsTrans()

    # IMPORT PIP -> has to be loaded before PIM because of terrain points
    if scs_globals.import_pip_file:
        lprint("I Importing PIP ...")
        pip_filepath = filepath + ".pip" + name_suffix
        if os.path.isfile(pip_filepath):
            lprint('\nD PIP filepath:\n  %s', (pip_filepath, ))
            # print('PIP filepath:\n  %s' % pip_filepath)
            result, prefab_locators = _pip.load(pip_filepath, terrain_points)
        else:
            lprint('\nI No PIP file.')
            # print('INFO - No PIP file.')

    # IMPORT PIM
    if scs_globals.import_pim_file or scs_globals.import_pis_file:
        lprint("I Importing PIM ...")
        pim_filepath = filepath + ".pim" + name_suffix
        if pim_filepath:
            if os.path.isfile(pim_filepath):
                lprint('\nD PIM filepath:\n  %s',
                       (_path_utils.readable_norm(pim_filepath), ))

                if pim_filepath.endswith(".pim"):
                    result, objects, locators, armature, skeleton, mats_info = _pim.load(
                        context,
                        pim_filepath,
                        terrain_points_trans=terrain_points)
                elif pim_filepath.endswith(".pim.ef"):
                    result, objects, locators, armature, skeleton, mats_info = _pim_ef.load(
                        context,
                        pim_filepath,
                        terrain_points_trans=terrain_points)
                else:
                    lprint(
                        "\nE Unknown PIM file extension! Shouldn't happen...")
            else:
                lprint('\nI No file found at %r!' %
                       (_path_utils.readable_norm(pim_filepath), ))
        else:
            lprint('\nI No filepath provided!')

    # IMPORT PIT
    bpy.context.view_layer.objects.active = None
    if scs_globals.import_pit_file:
        lprint("I Importing PIT ...")
        pit_filepath = filepath + ".pit" + name_suffix
        if os.path.isfile(pit_filepath):
            lprint('\nD PIT filepath:\n  %s', (pit_filepath, ))
            # print('PIT filepath:\n  %s' % pit_filepath)
            result, loaded_variants, loaded_looks = _pit.load(pit_filepath)
        else:
            lprint('\nI No PIT file.')
            # print('INFO - No PIT file.')

    # IMPORT PIC
    if scs_globals.import_pic_file:
        lprint("I Importing PIC ...")
        pic_filepath = filepath + ".pic" + name_suffix
        if os.path.isfile(pic_filepath):
            lprint('\nD PIC filepath:\n  %s', (pic_filepath, ))
            # print('PIC filepath:\n  %s' % pic_filepath)
            result, collision_locators = _pic.load(pic_filepath)
        else:
            lprint('\nI No PIC file.')
            # print('INFO - No PIC file.')

    # SETUP 'SCS GAME OBJECTS'
    lprint("I Setup of SCS game object ...")
    for item in collision_locators:
        locators.append(item)
    for item in prefab_locators:
        locators.append(item)
    path, filename = os.path.split(filepath)
    if objects or locators or (armature and skeleton):
        scs_root_object = _create_scs_root_object(filename, loaded_variants,
                                                  loaded_looks, mats_info,
                                                  objects, locators, armature)

        # Additionally if user wants to have automatically set custom export path, then let him have it :P
        if scs_globals.import_preserve_path_for_export:
            relative_export_path = _path_utils.relative_path(
                scs_globals.scs_project_path, path)
            if path.startswith(scs_globals.scs_project_path
                               ) and relative_export_path != path:
                scs_root_object.scs_props.scs_root_object_export_filepath = relative_export_path
                scs_root_object.scs_props.scs_root_object_allow_custom_path = True
            else:
                lprint(
                    "W Can not preserve import path for export on import SCS Root %r, "
                    "as import was done from outside of current SCS Project Base Path!",
                    (scs_root_object.name, ))

    # IMPORT PIS
    if scs_globals.import_pis_file:
        lprint("I Importing PIS ...")
        # pis file path is created from directory of pim file and skeleton definition inside pim header
        pis_filepath = os.path.dirname(filepath) + os.sep + skeleton
        if os.path.isfile(pis_filepath):
            lprint('\nD PIS filepath:\n  %s', (pis_filepath, ))

            # strip off name suffix from skeleton path
            skeleton = skeleton[:-len(name_suffix)]

            # fill in custom data if PIS file is from other directory
            if skeleton[:-4] != scs_root_object.name:
                armature.scs_props.scs_skeleton_custom_export_dirpath = "//" + os.path.relpath(
                    os.path.dirname(pis_filepath),
                    scs_globals.scs_project_path)
                armature.scs_props.scs_skeleton_custom_name = os.path.basename(
                    skeleton[:-4])

            bones = _pis.load(pis_filepath, armature)
        else:
            bones = None
            lprint('\nI No PIS file.')

        # IMPORT PIA
        if scs_globals.import_pia_file and bones:
            lprint("I Importing PIAs ...")
            basepath = os.path.dirname(filepath)
            # Search for PIA files in model's directory and its subdirectiories...
            lprint('\nD Searching the directory for PIA files:\n   %s',
                   (basepath, ))
            # print('\nSearching the directory for PIA files:\n   %s' % str(basepath))
            pia_files = []
            index = 0
            for root, dirs, files in os.walk(basepath):
                if not scs_globals.import_include_subdirs_for_pia:
                    if index > 0:
                        break
                # print('  root: %s - dirs: %s - files: %s' % (str(root), str(dirs), str(files)))
                for file in files:
                    if file.endswith(".pia" + name_suffix):
                        pia_filepath = os.path.join(root, file)
                        pia_files.append(pia_filepath)
                index += 1

            if len(pia_files) > 0:
                lprint('D PIA files found:')
                for pia_filepath in pia_files:
                    lprint('D %r', pia_filepath)
                # print('armature: %s\nskeleton: %r\nbones: %s\n' % (str(armature), str(skeleton), str(bones)))
                _pia.load(scs_root_object, pia_files, armature, pis_filepath,
                          bones)
            else:
                lprint('\nI No PIA files.')

    # fix scene objects count so it won't trigger copy cycle
    bpy.context.scene.scs_cached_num_objects = len(bpy.context.scene.objects)

    # FINAL FEEDBACK
    bpy.context.window.cursor_modal_restore()
    if suppress_reports:
        lprint('\nI Import compleeted in %.3f sec.', time.time() - t)
    else:
        lprint('\nI Import compleeted in %.3f sec.',
               time.time() - t,
               report_errors=True,
               report_warnings=True)

    return True
Example #2
0
def load(context, filepath):
    """

    :param context: Blender Context currently used for window_manager.update_progress and bpy_object_utils.object_data_add
    :type context: bpy.types.Context
    :param filepath: File path to be imported
    :type filepath: str
    :return: Return state statuses (Usually 'FINISHED')
    :rtype: dict
    """
    import time

    t = time.time()
    bpy.context.window.cursor_modal_set('WAIT')
    scs_globals = _get_scs_globals()
    lprint("", report_errors=-1, report_warnings=-1)  # Clear the 'error_messages' and 'warning_messages'

    collision_locators = []
    prefab_locators = []
    loaded_variants = []
    loaded_looks = []
    objects = []
    locators = []
    mats_info = []
    scs_root_object = skeleton = bones = armature = None

    # TRANSITIONAL STRUCTURES
    terrain_points = TerrainPntsTrans()

    # IMPORT PIP -> has to be loaded before PIM because of terrain points
    if scs_globals.import_pip_file:
        pip_filepath = str(filepath[:-1] + 'p')
        if os.path.isfile(pip_filepath):
            lprint('\nD PIP filepath:\n  %s', (pip_filepath,))
            # print('PIP filepath:\n  %s' % pip_filepath)
            result, prefab_locators = _pip.load(pip_filepath, terrain_points)
        else:
            lprint('\nI No PIP file.')
            # print('INFO - No PIP file.')

    # IMPORT PIM
    if scs_globals.import_pim_file or scs_globals.import_pis_file:
        if filepath:
            if os.path.isfile(filepath):
                lprint('\nD PIM filepath:\n  %s', (_path_utils.readable_norm(filepath),))
                result, objects, locators, armature, skeleton, mats_info = _pim.load(
                    context,
                    filepath,
                    terrain_points_trans=terrain_points
                )
                # print('  armature:\n%s\n  skeleton:\n%s' % (str(armature), str(skeleton)))
            else:
                lprint('\nI No file found at %r!' % (_path_utils.readable_norm(filepath),))
        else:
            lprint('\nI No filepath provided!')

    # IMPORT PIT
    bpy.context.scene.objects.active = None
    if scs_globals.import_pit_file:
        pit_filepath = str(filepath[:-1] + 't')
        if os.path.isfile(pit_filepath):
            lprint('\nD PIT filepath:\n  %s', (pit_filepath,))
            # print('PIT filepath:\n  %s' % pit_filepath)
            result, loaded_variants, loaded_looks = _pit.load(pit_filepath)
        else:
            lprint('\nI No PIT file.')
            # print('INFO - No PIT file.')

    # IMPORT PIC
    if scs_globals.import_pic_file:
        pic_filepath = str(filepath[:-1] + 'c')
        if os.path.isfile(pic_filepath):
            lprint('\nD PIC filepath:\n  %s', (pic_filepath,))
            # print('PIC filepath:\n  %s' % pic_filepath)
            result, collision_locators = _pic.load(pic_filepath)
        else:
            lprint('\nI No PIC file.')
            # print('INFO - No PIC file.')

    # SETUP 'SCS GAME OBJECTS'
    for item in collision_locators:
        locators.append(item)
    for item in prefab_locators:
        locators.append(item)
    path, file = os.path.split(filepath)
    # print('  path: %r\n  file: %r' % (path, file))
    lod_name, ext = os.path.splitext(file)
    if objects or locators or (armature and skeleton):
        scs_root_object = _create_scs_root_object(lod_name, loaded_variants, loaded_looks, mats_info, objects, locators, armature)

    # IMPORT PIS
    if scs_globals.import_pis_file:
        # pis file path is created from directory of pim file and skeleton definition inside pim header
        pis_filepath = os.path.dirname(filepath) + os.sep + skeleton
        if os.path.isfile(pis_filepath):
            lprint('\nD PIS filepath:\n  %s', (pis_filepath,))

            # fill in custom data if PIS file is from other directory
            if skeleton[:-4] != scs_root_object.name:
                armature.scs_props.scs_skeleton_custom_export_dirpath = "//" + os.path.relpath(os.path.dirname(pis_filepath),
                                                                                               scs_globals.scs_project_path)
                armature.scs_props.scs_skeleton_custom_name = os.path.basename(skeleton[:-4])

            bones = _pis.load(pis_filepath, armature)
        else:
            bones = None
            lprint('\nI No PIS file.')

        # IMPORT PIA
        if scs_globals.import_pia_file and bones:
            basepath = os.path.dirname(filepath)
            # Search for PIA files in model's directory and its subdirectiories...
            lprint('\nD Searching the directory for PIA files:\n   %s', (basepath,))
            # print('\nSearching the directory for PIA files:\n   %s' % str(basepath))
            pia_files = []
            index = 0
            for root, dirs, files in os.walk(basepath):
                if not scs_globals.include_subdirs_for_pia:
                    if index > 0:
                        break
                # print('  root: %s - dirs: %s - files: %s' % (str(root), str(dirs), str(files)))
                for file in files:
                    if file.endswith(".pia"):
                        pia_filepath = os.path.join(root, file)
                        pia_files.append(pia_filepath)
                index += 1

            if len(pia_files) > 0:
                lprint('D PIA files found:')
                for pia_filepath in pia_files:
                    lprint('D %r', pia_filepath)
                # print('armature: %s\nskeleton: %r\nbones: %s\n' % (str(armature), str(skeleton), str(bones)))
                _pia.load(scs_root_object, pia_files, armature, pis_filepath, bones)
            else:
                lprint('\nI No PIA files.')

    # fix scene objects count so it won't trigger copy cycle
    bpy.context.scene.scs_cached_num_objects = len(bpy.context.scene.objects)

    # Turn on Textured Solid in 3D view...
    for bl_screen in bpy.data.screens:
        for bl_area in bl_screen.areas:
            for bl_space in bl_area.spaces:
                if bl_space.type == 'VIEW_3D':
                    bl_space.show_textured_solid = True

    # Turn on GLSL in 3D view...
    bpy.context.scene.game_settings.material_mode = 'GLSL'

    # Turn on "Frame Dropping" for animation playback...
    bpy.context.scene.use_frame_drop = True

    # FINAL FEEDBACK
    bpy.context.window.cursor_modal_restore()
    lprint('\nI Import compleeted in %.3f sec.', time.time() - t, report_errors=True, report_warnings=True)
    return True
Example #3
0
def load(context, filepath):
    """

    :param context: Blender Context currently used for window_manager.update_progress and bpy_object_utils.object_data_add
    :type context: bpy.types.Context
    :param filepath: File path to be imported
    :type filepath: str
    :return: Return state statuses (Usually 'FINISHED')
    :rtype: dict
    """
    import time

    t = time.time()
    bpy.context.window.cursor_modal_set('WAIT')
    scs_globals = _get_scs_globals()
    lprint("", report_errors=-1, report_warnings=-1
           )  # Clear the 'error_messages' and 'warning_messages'

    collision_locators = []
    prefab_locators = []
    loaded_variants = []
    loaded_looks = []
    objects = []
    locators = []
    mats_info = []
    scs_root_object = skeleton = bones = armature = None

    # TRANSITIONAL STRUCTURES
    terrain_points = TerrainPntsTrans()

    # IMPORT PIP -> has to be loaded before PIM because of terrain points
    if scs_globals.import_pip_file:
        pip_filepath = str(filepath[:-1] + 'p')
        if os.path.isfile(pip_filepath):
            lprint('\nD PIP filepath:\n  %s', (pip_filepath, ))
            # print('PIP filepath:\n  %s' % pip_filepath)
            result, prefab_locators = _pip.load(pip_filepath, terrain_points)
        else:
            lprint('\nI No PIP file.')
            # print('INFO - No PIP file.')

    # IMPORT PIM
    if scs_globals.import_pim_file or scs_globals.import_pis_file:
        if filepath:
            if os.path.isfile(filepath):
                lprint('\nD PIM filepath:\n  %s',
                       (_path_utils.readable_norm(filepath), ))
                result, objects, locators, armature, skeleton, mats_info = _pim.load(
                    context, filepath, terrain_points_trans=terrain_points)
                # print('  armature:\n%s\n  skeleton:\n%s' % (str(armature), str(skeleton)))
            else:
                lprint('\nI No file found at %r!' %
                       (_path_utils.readable_norm(filepath), ))
        else:
            lprint('\nI No filepath provided!')

    # IMPORT PIT
    bpy.context.scene.objects.active = None
    if scs_globals.import_pit_file:
        pit_filepath = str(filepath[:-1] + 't')
        if os.path.isfile(pit_filepath):
            lprint('\nD PIT filepath:\n  %s', (pit_filepath, ))
            # print('PIT filepath:\n  %s' % pit_filepath)
            result, loaded_variants, loaded_looks = _pit.load(pit_filepath)
        else:
            lprint('\nI No PIT file.')
            # print('INFO - No PIT file.')

    # IMPORT PIC
    if scs_globals.import_pic_file:
        pic_filepath = str(filepath[:-1] + 'c')
        if os.path.isfile(pic_filepath):
            lprint('\nD PIC filepath:\n  %s', (pic_filepath, ))
            # print('PIC filepath:\n  %s' % pic_filepath)
            result, collision_locators = _pic.load(pic_filepath)
        else:
            lprint('\nI No PIC file.')
            # print('INFO - No PIC file.')

    # SETUP 'SCS GAME OBJECTS'
    for item in collision_locators:
        locators.append(item)
    for item in prefab_locators:
        locators.append(item)
    path, file = os.path.split(filepath)
    # print('  path: %r\n  file: %r' % (path, file))
    lod_name, ext = os.path.splitext(file)
    if objects or locators or (armature and skeleton):
        scs_root_object = _create_scs_root_object(lod_name, loaded_variants,
                                                  loaded_looks, mats_info,
                                                  objects, locators, armature)

        # Additionally if user wants to have automatically set custom export path, then let him have it :P
        if scs_globals.import_preserve_path_for_export:
            relative_export_path = _path_utils.relative_path(
                scs_globals.scs_project_path, path)
            if path.startswith(scs_globals.scs_project_path
                               ) and relative_export_path != path:
                scs_root_object.scs_props.scs_root_object_export_filepath = relative_export_path
                scs_root_object.scs_props.scs_root_object_allow_custom_path = True
            else:
                lprint(
                    "W Can not preserve import path for export on import SCS Root %r, "
                    "as import was done from outside of current SCS Project Base Path!",
                    (scs_root_object.name, ))

    # IMPORT PIS
    if scs_globals.import_pis_file:
        # pis file path is created from directory of pim file and skeleton definition inside pim header
        pis_filepath = os.path.dirname(filepath) + os.sep + skeleton
        if os.path.isfile(pis_filepath):
            lprint('\nD PIS filepath:\n  %s', (pis_filepath, ))

            # fill in custom data if PIS file is from other directory
            if skeleton[:-4] != scs_root_object.name:
                armature.scs_props.scs_skeleton_custom_export_dirpath = "//" + os.path.relpath(
                    os.path.dirname(pis_filepath),
                    scs_globals.scs_project_path)
                armature.scs_props.scs_skeleton_custom_name = os.path.basename(
                    skeleton[:-4])

            bones = _pis.load(pis_filepath, armature)
        else:
            bones = None
            lprint('\nI No PIS file.')

        # IMPORT PIA
        if scs_globals.import_pia_file and bones:
            basepath = os.path.dirname(filepath)
            # Search for PIA files in model's directory and its subdirectiories...
            lprint('\nD Searching the directory for PIA files:\n   %s',
                   (basepath, ))
            # print('\nSearching the directory for PIA files:\n   %s' % str(basepath))
            pia_files = []
            index = 0
            for root, dirs, files in os.walk(basepath):
                if not scs_globals.import_include_subdirs_for_pia:
                    if index > 0:
                        break
                # print('  root: %s - dirs: %s - files: %s' % (str(root), str(dirs), str(files)))
                for file in files:
                    if file.endswith(".pia"):
                        pia_filepath = os.path.join(root, file)
                        pia_files.append(pia_filepath)
                index += 1

            if len(pia_files) > 0:
                lprint('D PIA files found:')
                for pia_filepath in pia_files:
                    lprint('D %r', pia_filepath)
                # print('armature: %s\nskeleton: %r\nbones: %s\n' % (str(armature), str(skeleton), str(bones)))
                _pia.load(scs_root_object, pia_files, armature, pis_filepath,
                          bones)
            else:
                lprint('\nI No PIA files.')

    # fix scene objects count so it won't trigger copy cycle
    bpy.context.scene.scs_cached_num_objects = len(bpy.context.scene.objects)

    # Turn on Textured Solid in 3D view...
    for bl_screen in bpy.data.screens:
        for bl_area in bl_screen.areas:
            for bl_space in bl_area.spaces:
                if bl_space.type == 'VIEW_3D':
                    bl_space.show_textured_solid = True

    # Turn on GLSL in 3D view...
    bpy.context.scene.game_settings.material_mode = 'GLSL'

    # Turn on "Frame Dropping" for animation playback...
    bpy.context.scene.use_frame_drop = True

    # FINAL FEEDBACK
    bpy.context.window.cursor_modal_restore()
    lprint('\nI Import compleeted in %.3f sec.',
           time.time() - t,
           report_errors=True,
           report_warnings=True)
    return True
Example #4
0
def load(root_object, pia_files, armature, pis_filepath=None, bones=None):
    scs_globals = _get_scs_globals()

    print("\n************************************")
    print("**      SCS PIA Importer          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    import_scale = scs_globals.import_scale
    ind = '    '
    imported_count = 0
    for pia_filepath in pia_files:
        # Check if PIA file is for the actual skeleton...
        if pis_filepath and bones:
            skeleton_match = _pix_container.fast_check_for_pia_skeleton(
                pia_filepath, pis_filepath)
        else:
            skeleton_match, pia_skeleton = _pix_container.utter_check_for_pia_skeleton(
                pia_filepath, armature)

            if skeleton_match:

                path = os.path.split(pia_filepath)[0]
                pia_skeleton = os.path.join(path, pia_skeleton)
                if os.path.isfile(pia_skeleton):
                    bones = _pis.load(pia_skeleton, armature, get_only=True)
                else:
                    lprint("\nE The filepath %r doesn't exist!",
                           (_path_utils.readable_norm(pia_skeleton), ))

            else:
                lprint(
                    str("E Animation doesn't match the skeleton. Animation won't be loaded!\n\t   "
                        "Animation file: %r"), (pia_filepath, ))

        if skeleton_match:
            lprint('I ++ "%s" IMPORTING animation data...',
                   (os.path.basename(pia_filepath), ))
            pia_container = _pix_container.get_data_from_file(
                pia_filepath, ind)
            if not pia_container:
                lprint('\nE File "%s" is empty!',
                       (_path_utils.readable_norm(pia_filepath), ))
                continue

            # TEST PRINTOUTS
            # ind = '  '
            # for section in pia_container:
            # print('SEC.: "%s"' % section.type)
            # for prop in section.props:
            # print('%sProp: %s' % (ind, prop))
            # for data in section.data:
            # print('%sdata: %s' % (ind, data))
            # for sec in section.sections:
            # print_section(sec, ind)
            # print('\nTEST - Source: "%s"' % pia_container[0].props[1][1])
            # print('')

            # TEST EXPORT
            # path, file = os.path.splitext(pia_filepath)
            # export_filepath = str(path + '_reex' + file)
            # result = pix_write.write_data(pia_container, export_filepath, ind)
            # if result == {'FINISHED'}:
            # Print(dump_level, '\nI Test export succesful! The new file:\n  "%s"', export_filepath)
            # else:
            # Print(dump_level, '\nE Test export failed! File:\n  "%s"', export_filepath)

            # LOAD HEADER
            format_version, source, f_type, animation_name, source_filename, author = _get_header(
                pia_container)
            if format_version != 3 or f_type != "Animation":
                continue

            # LOAD GLOBALS
            skeleton, total_time, bone_channel_count, custom_channel_count = _get_globals(
                pia_container)

            # CREATE ANIMATION ACTIONS
            anim_action = bpy.data.actions.new(animation_name + "_action")
            anim_action.use_fake_user = True
            anim_data = armature.animation_data if armature.animation_data else armature.animation_data_create(
            )
            anim_data.action = anim_action

            # LOAD BONE CHANNELS
            bone_channels = _get_anim_channels(pia_container,
                                               section_name="BoneChannel")
            if len(bone_channels) > 0:

                for bone_name in bone_channels:

                    if bone_name in armature.data.bones:
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = bone_channels[bone_name][0]
                        keyframe_count = bone_channels[bone_name][1]
                        '''
                        streams = bone_channels[bone_name][2]

                        # CREATE ANIMATION GROUP
                        anim_group = anim_action.groups.new(bone_name)
                        armature.pose.bones[
                            bone_name].rotation_mode = 'XYZ'  # Set rotation mode.

                        # use pose bone scale set on PIS import
                        init_scale = Vector((1, 1, 1))
                        if _BONE_consts.init_scale_key in armature.pose.bones[
                                bone_name]:
                            init_scale = armature.pose.bones[bone_name][
                                _BONE_consts.init_scale_key]

                        # CREATE FCURVES
                        (pos_fcurves, rot_fcurves,
                         sca_fcurves) = _create_fcurves(anim_action,
                                                        anim_group,
                                                        str('pose.bones["' +
                                                            bone_name + '"]'),
                                                        rot_euler=True)

                        # GET BONE REST POSITION MATRIX
                        bone_rest_matrix_scs = bones[bone_name][1].transposed()
                        parent_bone_name = bones[bone_name][0]
                        if parent_bone_name in bones:
                            parent_bone_rest_matrix_scs = bones[
                                parent_bone_name][1].transposed()
                        else:
                            parent_bone_rest_matrix_scs = Matrix()
                            parent_bone_rest_matrix_scs.identity()

                        for key_time_i, key_time in enumerate(streams[0]):
                            keyframe = key_time_i + 1

                            # GET BONE ANIMATION MATRIX
                            bone_animation_matrix_scs = streams[1][
                                key_time_i].transposed()

                            # CREATE DELTA MATRIX
                            delta_matrix = _get_delta_matrix(
                                bone_rest_matrix_scs,
                                parent_bone_rest_matrix_scs,
                                bone_animation_matrix_scs, import_scale)

                            # DECOMPOSE ANIMATION MATRIX
                            location, rotation, scale = delta_matrix.decompose(
                            )

                            # CALCULATE CURRENT SCALE - subtract difference between initial bone scale and current scale from 1
                            # NOTE: if imported PIS had initial bone scale different than 1,
                            # initial scale was saved into pose bones custom properties and
                            # has to be used here as bones after import in Blender always have scale of 1
                            scale = Vector((1 + scale[0] - init_scale[0],
                                            1 + scale[1] - init_scale[1],
                                            1 + scale[2] - init_scale[2]))

                            # NOTE: this scaling rotation switch came from UK variants which had scale -1
                            loc, rot, sca = bone_rest_matrix_scs.decompose()
                            if sca.y < 0:
                                rotation.y *= -1
                            if sca.z < 0:
                                rotation.z *= -1

                            rotation = rotation.to_euler('XYZ')

                            # BUILD TRANSFORMATION CURVES
                            for i in range(0, 3):
                                pos_fcurves[i].keyframe_points.insert(
                                    frame=float(keyframe),
                                    value=location[i],
                                    options={'FAST'})
                                rot_fcurves[i].keyframe_points.insert(
                                    frame=float(keyframe),
                                    value=rotation[i],
                                    options={'FAST'})
                                sca_fcurves[i].keyframe_points.insert(
                                    frame=float(keyframe),
                                    value=scale[i],
                                    options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        color_mode = 'AUTO_RAINBOW'  # Or better 'AUTO_RGB'?
                        for curve in pos_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in rot_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in sca_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'

                        for curve in rot_fcurves:
                            _animation_utils.apply_euler_filter(curve)

            # LOAD CUSTOM CHANNELS (ARMATURE OFFSET ANIMATION)
            custom_channels = _get_anim_channels(pia_container,
                                                 section_name="CustomChannel")
            if len(custom_channels) > 0:
                for channel_name in custom_channels:
                    # print(' >>> channel %r - %s' % (channel_name, str(custom_channels[channel_name])))
                    if channel_name == 'Prism Movement':
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = custom_channels[channel_name][0]
                        keyframe_count = custom_channels[channel_name][1]
                        '''
                        streams = custom_channels[channel_name][2]
                        # print('  channel %r - streams %s - keyframes %s' % (channel_name, stream_count, keyframe_count))

                        # CREATE ANIMATION GROUP
                        # anim_group = anim_action.groups.new(channel_name)
                        anim_group = anim_action.groups.new('Location')
                        # armature.[channel_name].rotation_mode = 'XYZ' ## Set rotation mode.
                        # active_bone = armature.data.bones[channel_name]
                        # parent_bone = active_bone.parent

                        # CREATE FCURVES
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, rot_euler=True,
                        # types='LocRotSca')
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, types='Loc')
                        fcurve_pos_x = anim_action.fcurves.new('location', 0)
                        fcurve_pos_y = anim_action.fcurves.new('location', 1)
                        fcurve_pos_z = anim_action.fcurves.new('location', 2)
                        fcurve_pos_x.group = anim_group
                        fcurve_pos_y.group = anim_group
                        fcurve_pos_z.group = anim_group
                        pos_fcurves = (fcurve_pos_x, fcurve_pos_y,
                                       fcurve_pos_z)

                        location = None
                        for key_time_i, key_time in enumerate(streams[0]):
                            # print(' key_time: %s' % str(key_time[0]))
                            # keyframe = key_time_i * (key_time[0] * 10) ## TODO: Do proper timing...
                            keyframe = key_time_i + 1
                            scs_offset = _convert_utils.change_to_scs_xyz_coordinates(
                                custom_channels[channel_name][2][1]
                                [key_time_i], import_scale)
                            offset = Vector(scs_offset)
                            if location is None:
                                location = offset
                            else:
                                location = location + offset
                            # print(' > location: %s' % str(location))

                            # BUILD TRANSLATION CURVES
                            pos_fcurves[0].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[0],
                                options={'FAST'})
                            pos_fcurves[1].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[1],
                                options={'FAST'})
                            pos_fcurves[2].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[2],
                                options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        for curve in pos_fcurves:
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                    else:
                        lprint('W Unknown channel %r in "%s" file.',
                               (channel_name, os.path.basename(pia_filepath)))

            # CREATE SCS ANIMATION
            animation = _animation_utils.add_animation_to_root(
                root_object, animation_name)
            animation.export = True
            animation.action = anim_action.name
            animation.anim_start = anim_action.frame_range[0]
            animation.anim_end = anim_action.frame_range[1]

            if total_time:
                animation.length = total_time

                # WARNING PRINTOUTS
                # if piece_count < 0: Print(dump_level, '\nW More Pieces found than were declared!')
                # if piece_count > 0: Print(dump_level, '\nW Some Pieces not found, but were declared!')
                # if dump_level > 1: print('')

            imported_count += 1
        else:
            lprint('I    "%s" file REJECTED',
                   (os.path.basename(pia_filepath), ))

    # at the end of batch import make sure to select last animation always
    if imported_count > 0:
        root_object.scs_props.active_scs_animation = len(
            root_object.scs_object_animation_inventory) - 1

    print("************************************")
    return imported_count
Example #5
0
def load(root_object, pia_files, armature, skeleton=None, bones=None):
    if not bones:
        bones = {}

    scs_globals = _get_scs_globals()

    print("\n************************************")
    print("**      SCS PIA Importer          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    import_scale = scs_globals.import_scale
    ind = '    '
    for pia_filepath in pia_files:
        # Check if PIA file is for the actual skeleton...
        if skeleton:
            skeleton_match = _fast_check_for_pia_skeleton(pia_filepath, skeleton)
        else:
            skeleton_match, skeleton = _utter_check_for_pia_skeleton(pia_filepath, armature)
            # print('%r - %s' %(os.path.basename(pia_filepath), skeleton_match))
            # print('  skeleton: %r' % skeleton)
            if skeleton_match:
                path = os.path.split(pia_filepath)[0]
                pis_filepath = os.path.join(path, skeleton)
                if os.path.isfile(pis_filepath):
                    # print('  pis_filepath: %r' % pis_filepath)
                    bones = _pis.load(pis_filepath, armature)
                else:
                    lprint("""\nE The filepath "%s" doesn't exist!""", (pis_filepath.replace("\\", "/"),))

        if skeleton_match:
            lprint('I ++ "%s" IMPORTING animation data...', (os.path.basename(pia_filepath),))
            pia_container, state = _pix_parser.read_data(pia_filepath, ind)
            if not pia_container:
                lprint('\nE File "%s" is empty!', (pia_filepath.replace("\\", "/"),))
                return {'CANCELLED'}
            if state == 'ERR':
                lprint('\nE File "%s" is not SCS Animation file!', (pia_filepath.replace("\\", "/"),))
                return {'CANCELLED'}

            # TEST PRINTOUTS
            # ind = '  '
            # for section in pia_container:
            # print('SEC.: "%s"' % section.type)
            # for prop in section.props:
            # print('%sProp: %s' % (ind, prop))
            # for data in section.data:
            # print('%sdata: %s' % (ind, data))
            # for sec in section.sections:
            # print_section(sec, ind)
            # print('\nTEST - Source: "%s"' % pia_container[0].props[1][1])
            # print('')

            # TEST EXPORT
            # path, file = os.path.splitext(pia_filepath)
            # export_filepath = str(path + '_reex' + file)
            # result = pix_write.write_data(pia_container, export_filepath, ind)
            # if result == {'FINISHED'}:
            # Print(dump_level, '\nI Test export succesful! The new file:\n  "%s"', export_filepath)
            # else:
            # Print(dump_level, '\nE Test export failed! File:\n  "%s"', export_filepath)

            # LOAD HEADER
            format_version, source, f_type, animation_name, source_filename, author = _get_header(pia_container)
            if format_version != 3 or f_type != "Animation":
                return {'CANCELLED'}

            # LOAD GLOBALS
            skeleton, total_time, bone_channel_count, custom_channel_count = _get_globals(pia_container)

            # CREATE ANIMATION ACTIONS
            anim_action = bpy.data.actions.new(animation_name)
            anim_action.use_fake_user = True
            if total_time:
                anim_action.scs_props.action_length = total_time
            anim_data = armature.animation_data_create()
            anim_data.action = anim_action

            # LOAD BONE CHANNELS
            # print(' * armature: %r' % armature.name)
            if bone_channel_count > 0:
                bone_channels = _get_anim_channels(pia_container, section_name="BoneChannel")

                # ...
                for bone_name in bone_channels:
                    # bone_name = channel[0]
                    if bone_name in armature.data.bones:
                        # print('%r is in armature %r' % (bone_name, armature.name))
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = bone_channels[bone_name][0]
                        keyframe_count = bone_channels[bone_name][1]
                        '''
                        streams = bone_channels[bone_name][2]
                        # print('  channel %r - streams %s - keyframes %s' % (bone_name, stream_count, keyframe_count))

                        # CREATE ANIMATION GROUP
                        anim_group = anim_action.groups.new(bone_name)
                        armature.pose.bones[bone_name].rotation_mode = 'XYZ'  # Set rotation mode.
                        active_bone = armature.data.bones[bone_name]
                        # parent_bone = active_bone.parent

                        # CREATE FCURVES
                        (pos_fcurves,
                         rot_fcurves,
                         sca_fcurves) = _create_fcurves(anim_action, anim_group, str('pose.bones["' + bone_name + '"]'))

                        # GET BONE REST POSITION MATRIX
                        bone_rest_matrix = active_bone.matrix_local
                        bone_rest_matrix_scs = bones[bone_name][1].transposed()
                        parent_bone_name = bones[bone_name][0]
                        if parent_bone_name in bones:
                            parent_bone_rest_matrix_scs = bones[parent_bone_name][1].transposed()
                        else:
                            parent_bone_rest_matrix_scs = Matrix()
                            parent_bone_rest_matrix_scs.identity()

                            # if bone_name in ('LeftHand1', 'LeftHand'):
                            # print('\n  %r - bone_rest_matrix_scs:\n%s' % (bone_name, bone_rest_matrix_scs))
                            # print('  %r - bone_rest_matrix:\n%s' % (bone_name, bone_rest_matrix))
                            # print('  %r - parent_bone_rest_matrix_scs:\n%s' % (bone_name, parent_bone_rest_matrix_scs))

                        for key_time_i, key_time in enumerate(streams[0]):
                            # print(' key_time: %s' % str(key_time[0]))
                            # keyframe = key_time_i * (key_time[0] * 10) ## TODO: Do proper timing...
                            keyframe = key_time_i + 1

                            # GET BONE ANIMATION MATRIX
                            bone_animation_matrix_scs = streams[1][key_time_i].transposed()
                            # if bone_name in ('LeftHand1', 'LeftHand') and key_time_i == 0: print('  %r - bone_animation_matrix_scs (%i):\n%s' % (
                            # bone_name, key_time_i, bone_animation_matrix_scs))

                            # CREATE DELTA MATRIX
                            delta_matrix = _get_delta_matrix(bone_rest_matrix, bone_rest_matrix_scs,
                                                             parent_bone_rest_matrix_scs, bone_animation_matrix_scs, import_scale)

                            # DECOMPOSE ANIMATION MATRIX
                            location, rotation, scale = delta_matrix.decompose()
                            # if bone_name in ('left_leg', 'root') and key_time_i == 0: print('  location:\n%s' % str(location))
                            rotation = rotation.to_euler('XYZ')

                            # BUILD TRANSLATION CURVES
                            pos_fcurves[0].keyframe_points.insert(frame=float(keyframe), value=location[0], options={'FAST'})
                            pos_fcurves[1].keyframe_points.insert(frame=float(keyframe), value=location[1], options={'FAST'})
                            pos_fcurves[2].keyframe_points.insert(frame=float(keyframe), value=location[2], options={'FAST'})

                            # BUILD ROTATION CURVES
                            rot_fcurves[0].keyframe_points.insert(frame=float(keyframe), value=rotation[0], options={'FAST'})
                            rot_fcurves[1].keyframe_points.insert(frame=float(keyframe), value=rotation[1], options={'FAST'})
                            rot_fcurves[2].keyframe_points.insert(frame=float(keyframe), value=rotation[2], options={'FAST'})

                            # BUILD SCALE CURVES
                            sca_fcurves[0].keyframe_points.insert(frame=float(keyframe), value=scale[0], options={'FAST'})
                            sca_fcurves[1].keyframe_points.insert(frame=float(keyframe), value=scale[1], options={'FAST'})
                            sca_fcurves[2].keyframe_points.insert(frame=float(keyframe), value=scale[2], options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        color_mode = 'AUTO_RAINBOW'  # Or better 'AUTO_RGB'?
                        for curve in pos_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in rot_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in sca_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'

                                # LOAD CUSTOM CHANNELS (ARMATURE OFFSET ANIMATION)
            # if custom_channel_count > 0: ## NOTE: Can't be used because exporter from Maya saves always 0 even if there are Custom Channels.
            custom_channels = _get_anim_channels(pia_container, section_name="CustomChannel")
            if len(custom_channels) > 0:
                for channel_name in custom_channels:
                    # print(' >>> channel %r - %s' % (channel_name, str(custom_channels[channel_name])))
                    if channel_name == 'Prism Movement':
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = custom_channels[channel_name][0]
                        keyframe_count = custom_channels[channel_name][1]
                        '''
                        streams = custom_channels[channel_name][2]
                        # print('  channel %r - streams %s - keyframes %s' % (channel_name, stream_count, keyframe_count))

                        # CREATE ANIMATION GROUP
                        # anim_group = anim_action.groups.new(channel_name)
                        anim_group = anim_action.groups.new('Location')
                        # armature.[channel_name].rotation_mode = 'XYZ' ## Set rotation mode.
                        # active_bone = armature.data.bones[channel_name]
                        # parent_bone = active_bone.parent

                        # CREATE FCURVES
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, rot_euler=True,
                        # types='LocRotSca')
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, types='Loc')
                        fcurve_pos_x = anim_action.fcurves.new('location', 0)
                        fcurve_pos_y = anim_action.fcurves.new('location', 1)
                        fcurve_pos_z = anim_action.fcurves.new('location', 2)
                        fcurve_pos_x.group = anim_group
                        fcurve_pos_y.group = anim_group
                        fcurve_pos_z.group = anim_group
                        pos_fcurves = (fcurve_pos_x, fcurve_pos_y, fcurve_pos_z)

                        location = None
                        for key_time_i, key_time in enumerate(streams[0]):
                            # print(' key_time: %s' % str(key_time[0]))
                            # keyframe = key_time_i * (key_time[0] * 10) ## TODO: Do proper timing...
                            keyframe = key_time_i + 1
                            scs_offset = _convert_utils.change_to_scs_xyz_coordinates(custom_channels[channel_name][2][1][key_time_i], import_scale)
                            offset = Vector(scs_offset)
                            if location is None:
                                location = offset
                            else:
                                location = location + offset
                            # print(' > location: %s' % str(location))

                            # BUILD TRANSLATION CURVES
                            pos_fcurves[0].keyframe_points.insert(frame=float(keyframe), value=location[0], options={'FAST'})
                            pos_fcurves[1].keyframe_points.insert(frame=float(keyframe), value=location[1], options={'FAST'})
                            pos_fcurves[2].keyframe_points.insert(frame=float(keyframe), value=location[2], options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        for curve in pos_fcurves:
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                    else:
                        lprint('W Unknown channel %r in "%s" file.', (channel_name, os.path.basename(pia_filepath)))

                        # CREATE SCS ANIMATION
            animation = _animation_utils.add_animation_to_root(root_object, animation_name)
            animation.export = True
            animation.action = anim_action.name
            animation.anim_start = anim_action.frame_range[0]
            animation.anim_end = anim_action.frame_range[1]
            # animation.anim_export_step =
            # animation.anim_export_filepath =
            if total_time:
                animation.length = total_time

                # WARNING PRINTOUTS
                # if piece_count < 0: Print(dump_level, '\nW More Pieces found than were declared!')
                # if piece_count > 0: Print(dump_level, '\nW Some Pieces not found, but were declared!')
                # if dump_level > 1: print('')
        else:
            lprint('I    "%s" file REJECTED', (os.path.basename(pia_filepath),))

    print("************************************")
    return {'FINISHED'}
Example #6
0
def load(root_object, pia_files, armature, pis_filepath=None, bones=None):
    scs_globals = _get_scs_globals()

    print("\n************************************")
    print("**      SCS PIA Importer          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    import_scale = scs_globals.import_scale
    ind = '    '
    imported_count = 0
    for pia_filepath in pia_files:
        # Check if PIA file is for the actual skeleton...
        if pis_filepath and bones:
            skeleton_match = _pix_container.fast_check_for_pia_skeleton(pia_filepath, pis_filepath)
        else:
            skeleton_match, pia_skeleton = _pix_container.utter_check_for_pia_skeleton(pia_filepath, armature)

            if skeleton_match:

                path = os.path.split(pia_filepath)[0]
                pia_skeleton = os.path.join(path, pia_skeleton)
                if os.path.isfile(pia_skeleton):
                    bones = _pis.load(pia_skeleton, armature, get_only=True)
                else:
                    lprint("\nE The filepath %r doesn't exist!", (pia_skeleton.replace("\\", "/"),))

            else:
                lprint(str("E Animation doesn't match the skeleton. Animation won't be loaded!\n\t   "
                           "Animation file: %r"), (pia_filepath,))

        if skeleton_match:
            lprint('I ++ "%s" IMPORTING animation data...', (os.path.basename(pia_filepath),))
            pia_container = _pix_container.get_data_from_file(pia_filepath, ind)
            if not pia_container:
                lprint('\nE File "%s" is empty!', (pia_filepath.replace("\\", "/"),))
                continue

            # TEST PRINTOUTS
            # ind = '  '
            # for section in pia_container:
            # print('SEC.: "%s"' % section.type)
            # for prop in section.props:
            # print('%sProp: %s' % (ind, prop))
            # for data in section.data:
            # print('%sdata: %s' % (ind, data))
            # for sec in section.sections:
            # print_section(sec, ind)
            # print('\nTEST - Source: "%s"' % pia_container[0].props[1][1])
            # print('')

            # TEST EXPORT
            # path, file = os.path.splitext(pia_filepath)
            # export_filepath = str(path + '_reex' + file)
            # result = pix_write.write_data(pia_container, export_filepath, ind)
            # if result == {'FINISHED'}:
            # Print(dump_level, '\nI Test export succesful! The new file:\n  "%s"', export_filepath)
            # else:
            # Print(dump_level, '\nE Test export failed! File:\n  "%s"', export_filepath)

            # LOAD HEADER
            format_version, source, f_type, animation_name, source_filename, author = _get_header(pia_container)
            if format_version != 3 or f_type != "Animation":
                continue

            # LOAD GLOBALS
            skeleton, total_time, bone_channel_count, custom_channel_count = _get_globals(pia_container)

            # CREATE ANIMATION ACTIONS
            anim_action = bpy.data.actions.new(animation_name + "_action")
            anim_action.use_fake_user = True
            anim_data = armature.animation_data if armature.animation_data else armature.animation_data_create()
            anim_data.action = anim_action

            # LOAD BONE CHANNELS
            bone_channels = _get_anim_channels(pia_container, section_name="BoneChannel")
            if len(bone_channels) > 0:

                for bone_name in bone_channels:

                    if bone_name in armature.data.bones:
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = bone_channels[bone_name][0]
                        keyframe_count = bone_channels[bone_name][1]
                        '''
                        streams = bone_channels[bone_name][2]

                        # CREATE ANIMATION GROUP
                        anim_group = anim_action.groups.new(bone_name)
                        armature.pose.bones[bone_name].rotation_mode = 'XYZ'  # Set rotation mode.

                        # use pose bone scale set on PIS import
                        init_scale = Vector((1, 1, 1))
                        if _BONE_consts.init_scale_key in armature.pose.bones[bone_name]:
                            init_scale = armature.pose.bones[bone_name][_BONE_consts.init_scale_key]

                        # CREATE FCURVES
                        (pos_fcurves,
                         rot_fcurves,
                         sca_fcurves) = _create_fcurves(anim_action, anim_group, str('pose.bones["' + bone_name + '"]'), rot_euler=True)

                        # GET BONE REST POSITION MATRIX
                        bone_rest_matrix_scs = bones[bone_name][1].transposed()
                        parent_bone_name = bones[bone_name][0]
                        if parent_bone_name in bones:
                            parent_bone_rest_matrix_scs = bones[parent_bone_name][1].transposed()
                        else:
                            parent_bone_rest_matrix_scs = Matrix()
                            parent_bone_rest_matrix_scs.identity()

                        for key_time_i, key_time in enumerate(streams[0]):
                            keyframe = key_time_i + 1

                            # GET BONE ANIMATION MATRIX
                            bone_animation_matrix_scs = streams[1][key_time_i].transposed()

                            # CREATE DELTA MATRIX
                            delta_matrix = _get_delta_matrix(bone_rest_matrix_scs, parent_bone_rest_matrix_scs, bone_animation_matrix_scs,
                                                             import_scale)

                            # DECOMPOSE ANIMATION MATRIX
                            location, rotation, scale = delta_matrix.decompose()

                            # CALCULATE CURRENT SCALE - subtract difference between initial bone scale and current scale from 1
                            # NOTE: if imported PIS had initial bone scale different than 1,
                            # initial scale was saved into pose bones custom properties and
                            # has to be used here as bones after import in Blender always have scale of 1
                            scale = Vector((1 + scale[0] - init_scale[0],
                                            1 + scale[1] - init_scale[1],
                                            1 + scale[2] - init_scale[2]))

                            # NOTE: this scaling rotation switch came from UK variants which had scale -1
                            loc, rot, sca = bone_rest_matrix_scs.decompose()
                            if sca.y < 0:
                                rotation.y *= -1
                            if sca.z < 0:
                                rotation.z *= -1

                            rotation = rotation.to_euler('XYZ')

                            # BUILD TRANSFORMATION CURVES
                            for i in range(0, 3):
                                pos_fcurves[i].keyframe_points.insert(frame=float(keyframe), value=location[i], options={'FAST'})
                                rot_fcurves[i].keyframe_points.insert(frame=float(keyframe), value=rotation[i], options={'FAST'})
                                sca_fcurves[i].keyframe_points.insert(frame=float(keyframe), value=scale[i], options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        color_mode = 'AUTO_RAINBOW'  # Or better 'AUTO_RGB'?
                        for curve in pos_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in rot_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in sca_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'

                        for curve in rot_fcurves:
                            _animation_utils.apply_euler_filter(curve)

            # LOAD CUSTOM CHANNELS (ARMATURE OFFSET ANIMATION)
            custom_channels = _get_anim_channels(pia_container, section_name="CustomChannel")
            if len(custom_channels) > 0:
                for channel_name in custom_channels:
                    # print(' >>> channel %r - %s' % (channel_name, str(custom_channels[channel_name])))
                    if channel_name == 'Prism Movement':
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = custom_channels[channel_name][0]
                        keyframe_count = custom_channels[channel_name][1]
                        '''
                        streams = custom_channels[channel_name][2]
                        # print('  channel %r - streams %s - keyframes %s' % (channel_name, stream_count, keyframe_count))

                        # CREATE ANIMATION GROUP
                        # anim_group = anim_action.groups.new(channel_name)
                        anim_group = anim_action.groups.new('Location')
                        # armature.[channel_name].rotation_mode = 'XYZ' ## Set rotation mode.
                        # active_bone = armature.data.bones[channel_name]
                        # parent_bone = active_bone.parent

                        # CREATE FCURVES
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, rot_euler=True,
                        # types='LocRotSca')
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, types='Loc')
                        fcurve_pos_x = anim_action.fcurves.new('location', 0)
                        fcurve_pos_y = anim_action.fcurves.new('location', 1)
                        fcurve_pos_z = anim_action.fcurves.new('location', 2)
                        fcurve_pos_x.group = anim_group
                        fcurve_pos_y.group = anim_group
                        fcurve_pos_z.group = anim_group
                        pos_fcurves = (fcurve_pos_x, fcurve_pos_y, fcurve_pos_z)

                        location = None
                        for key_time_i, key_time in enumerate(streams[0]):
                            # print(' key_time: %s' % str(key_time[0]))
                            # keyframe = key_time_i * (key_time[0] * 10) ## TODO: Do proper timing...
                            keyframe = key_time_i + 1
                            scs_offset = _convert_utils.change_to_scs_xyz_coordinates(custom_channels[channel_name][2][1][key_time_i], import_scale)
                            offset = Vector(scs_offset)
                            if location is None:
                                location = offset
                            else:
                                location = location + offset
                            # print(' > location: %s' % str(location))

                            # BUILD TRANSLATION CURVES
                            pos_fcurves[0].keyframe_points.insert(frame=float(keyframe), value=location[0], options={'FAST'})
                            pos_fcurves[1].keyframe_points.insert(frame=float(keyframe), value=location[1], options={'FAST'})
                            pos_fcurves[2].keyframe_points.insert(frame=float(keyframe), value=location[2], options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        for curve in pos_fcurves:
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                    else:
                        lprint('W Unknown channel %r in "%s" file.', (channel_name, os.path.basename(pia_filepath)))

            # CREATE SCS ANIMATION
            animation = _animation_utils.add_animation_to_root(root_object, animation_name)
            animation.export = True
            animation.action = anim_action.name
            animation.anim_start = anim_action.frame_range[0]
            animation.anim_end = anim_action.frame_range[1]

            if total_time:
                animation.length = total_time

                # WARNING PRINTOUTS
                # if piece_count < 0: Print(dump_level, '\nW More Pieces found than were declared!')
                # if piece_count > 0: Print(dump_level, '\nW Some Pieces not found, but were declared!')
                # if dump_level > 1: print('')

            imported_count += 1
        else:
            lprint('I    "%s" file REJECTED', (os.path.basename(pia_filepath),))

    # at the end of batch import make sure to select last animation always
    if imported_count > 0:
        root_object.scs_props.active_scs_animation = len(root_object.scs_object_animation_inventory) - 1

    print("************************************")
    return imported_count
Example #7
0
def load(root_object, pia_files, armature, skeleton=None, bones=None):
    if not bones:
        bones = {}

    scs_globals = _get_scs_globals()

    print("\n************************************")
    print("**      SCS PIA Importer          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    import_scale = scs_globals.import_scale
    ind = '    '
    for pia_filepath in pia_files:
        # Check if PIA file is for the actual skeleton...
        if skeleton:
            skeleton_match = _fast_check_for_pia_skeleton(
                pia_filepath, skeleton)
        else:
            skeleton_match, skeleton = _utter_check_for_pia_skeleton(
                pia_filepath, armature)
            # print('%r - %s' %(os.path.basename(pia_filepath), skeleton_match))
            # print('  skeleton: %r' % skeleton)
            if skeleton_match:
                path = os.path.split(pia_filepath)[0]
                pis_filepath = os.path.join(path, skeleton)
                if os.path.isfile(pis_filepath):
                    # print('  pis_filepath: %r' % pis_filepath)
                    bones = _pis.load(pis_filepath, armature)
                else:
                    lprint("""\nE The filepath "%s" doesn't exist!""",
                           (pis_filepath.replace("\\", "/"), ))

        if skeleton_match:
            lprint('I ++ "%s" IMPORTING animation data...',
                   (os.path.basename(pia_filepath), ))
            pia_container, state = _pix_parser.read_data(pia_filepath, ind)
            if not pia_container:
                lprint('\nE File "%s" is empty!',
                       (pia_filepath.replace("\\", "/"), ))
                return {'CANCELLED'}
            if state == 'ERR':
                lprint('\nE File "%s" is not SCS Animation file!',
                       (pia_filepath.replace("\\", "/"), ))
                return {'CANCELLED'}

            # TEST PRINTOUTS
            # ind = '  '
            # for section in pia_container:
            # print('SEC.: "%s"' % section.type)
            # for prop in section.props:
            # print('%sProp: %s' % (ind, prop))
            # for data in section.data:
            # print('%sdata: %s' % (ind, data))
            # for sec in section.sections:
            # print_section(sec, ind)
            # print('\nTEST - Source: "%s"' % pia_container[0].props[1][1])
            # print('')

            # TEST EXPORT
            # path, file = os.path.splitext(pia_filepath)
            # export_filepath = str(path + '_reex' + file)
            # result = pix_write.write_data(pia_container, export_filepath, ind)
            # if result == {'FINISHED'}:
            # Print(dump_level, '\nI Test export succesful! The new file:\n  "%s"', export_filepath)
            # else:
            # Print(dump_level, '\nE Test export failed! File:\n  "%s"', export_filepath)

            # LOAD HEADER
            format_version, source, f_type, animation_name, source_filename, author = _get_header(
                pia_container)
            if format_version != 3 or f_type != "Animation":
                return {'CANCELLED'}

            # LOAD GLOBALS
            skeleton, total_time, bone_channel_count, custom_channel_count = _get_globals(
                pia_container)

            # CREATE ANIMATION ACTIONS
            anim_action = bpy.data.actions.new(animation_name)
            anim_action.use_fake_user = True
            if total_time:
                anim_action.scs_props.action_length = total_time
            anim_data = armature.animation_data_create()
            anim_data.action = anim_action

            # LOAD BONE CHANNELS
            # print(' * armature: %r' % armature.name)
            if bone_channel_count > 0:
                bone_channels = _get_anim_channels(pia_container,
                                                   section_name="BoneChannel")

                # ...
                for bone_name in bone_channels:
                    # bone_name = channel[0]
                    if bone_name in armature.data.bones:
                        # print('%r is in armature %r' % (bone_name, armature.name))
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = bone_channels[bone_name][0]
                        keyframe_count = bone_channels[bone_name][1]
                        '''
                        streams = bone_channels[bone_name][2]
                        # print('  channel %r - streams %s - keyframes %s' % (bone_name, stream_count, keyframe_count))

                        # CREATE ANIMATION GROUP
                        anim_group = anim_action.groups.new(bone_name)
                        armature.pose.bones[
                            bone_name].rotation_mode = 'XYZ'  # Set rotation mode.
                        active_bone = armature.data.bones[bone_name]
                        # parent_bone = active_bone.parent

                        # CREATE FCURVES
                        (pos_fcurves, rot_fcurves,
                         sca_fcurves) = _create_fcurves(
                             anim_action, anim_group,
                             str('pose.bones["' + bone_name + '"]'))

                        # GET BONE REST POSITION MATRIX
                        bone_rest_matrix = active_bone.matrix_local
                        bone_rest_matrix_scs = bones[bone_name][1].transposed()
                        parent_bone_name = bones[bone_name][0]
                        if parent_bone_name in bones:
                            parent_bone_rest_matrix_scs = bones[
                                parent_bone_name][1].transposed()
                        else:
                            parent_bone_rest_matrix_scs = Matrix()
                            parent_bone_rest_matrix_scs.identity()

                            # if bone_name in ('LeftHand1', 'LeftHand'):
                            # print('\n  %r - bone_rest_matrix_scs:\n%s' % (bone_name, bone_rest_matrix_scs))
                            # print('  %r - bone_rest_matrix:\n%s' % (bone_name, bone_rest_matrix))
                            # print('  %r - parent_bone_rest_matrix_scs:\n%s' % (bone_name, parent_bone_rest_matrix_scs))

                        for key_time_i, key_time in enumerate(streams[0]):
                            # print(' key_time: %s' % str(key_time[0]))
                            # keyframe = key_time_i * (key_time[0] * 10) ## TODO: Do proper timing...
                            keyframe = key_time_i + 1

                            # GET BONE ANIMATION MATRIX
                            bone_animation_matrix_scs = streams[1][
                                key_time_i].transposed()
                            # if bone_name in ('LeftHand1', 'LeftHand') and key_time_i == 0: print('  %r - bone_animation_matrix_scs (%i):\n%s' % (
                            # bone_name, key_time_i, bone_animation_matrix_scs))

                            # CREATE DELTA MATRIX
                            delta_matrix = _get_delta_matrix(
                                bone_rest_matrix, bone_rest_matrix_scs,
                                parent_bone_rest_matrix_scs,
                                bone_animation_matrix_scs, import_scale)

                            # DECOMPOSE ANIMATION MATRIX
                            location, rotation, scale = delta_matrix.decompose(
                            )
                            # if bone_name in ('left_leg', 'root') and key_time_i == 0: print('  location:\n%s' % str(location))
                            rotation = rotation.to_euler('XYZ')

                            # BUILD TRANSLATION CURVES
                            pos_fcurves[0].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[0],
                                options={'FAST'})
                            pos_fcurves[1].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[1],
                                options={'FAST'})
                            pos_fcurves[2].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[2],
                                options={'FAST'})

                            # BUILD ROTATION CURVES
                            rot_fcurves[0].keyframe_points.insert(
                                frame=float(keyframe),
                                value=rotation[0],
                                options={'FAST'})
                            rot_fcurves[1].keyframe_points.insert(
                                frame=float(keyframe),
                                value=rotation[1],
                                options={'FAST'})
                            rot_fcurves[2].keyframe_points.insert(
                                frame=float(keyframe),
                                value=rotation[2],
                                options={'FAST'})

                            # BUILD SCALE CURVES
                            sca_fcurves[0].keyframe_points.insert(
                                frame=float(keyframe),
                                value=scale[0],
                                options={'FAST'})
                            sca_fcurves[1].keyframe_points.insert(
                                frame=float(keyframe),
                                value=scale[1],
                                options={'FAST'})
                            sca_fcurves[2].keyframe_points.insert(
                                frame=float(keyframe),
                                value=scale[2],
                                options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        color_mode = 'AUTO_RAINBOW'  # Or better 'AUTO_RGB'?
                        for curve in pos_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in rot_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                        for curve in sca_fcurves:
                            curve.color_mode = color_mode
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'

                                # LOAD CUSTOM CHANNELS (ARMATURE OFFSET ANIMATION)
            # if custom_channel_count > 0: ## NOTE: Can't be used because exporter from Maya saves always 0 even if there are Custom Channels.
            custom_channels = _get_anim_channels(pia_container,
                                                 section_name="CustomChannel")
            if len(custom_channels) > 0:
                for channel_name in custom_channels:
                    # print(' >>> channel %r - %s' % (channel_name, str(custom_channels[channel_name])))
                    if channel_name == 'Prism Movement':
                        '''
                        NOTE: skipped for now as no data needs to be readed
                        stream_count = custom_channels[channel_name][0]
                        keyframe_count = custom_channels[channel_name][1]
                        '''
                        streams = custom_channels[channel_name][2]
                        # print('  channel %r - streams %s - keyframes %s' % (channel_name, stream_count, keyframe_count))

                        # CREATE ANIMATION GROUP
                        # anim_group = anim_action.groups.new(channel_name)
                        anim_group = anim_action.groups.new('Location')
                        # armature.[channel_name].rotation_mode = 'XYZ' ## Set rotation mode.
                        # active_bone = armature.data.bones[channel_name]
                        # parent_bone = active_bone.parent

                        # CREATE FCURVES
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, rot_euler=True,
                        # types='LocRotSca')
                        # pos_fcurves, rot_fcurves, sca_fcurves = _create_fcurves(anim_action, anim_group, anim_curve, types='Loc')
                        fcurve_pos_x = anim_action.fcurves.new('location', 0)
                        fcurve_pos_y = anim_action.fcurves.new('location', 1)
                        fcurve_pos_z = anim_action.fcurves.new('location', 2)
                        fcurve_pos_x.group = anim_group
                        fcurve_pos_y.group = anim_group
                        fcurve_pos_z.group = anim_group
                        pos_fcurves = (fcurve_pos_x, fcurve_pos_y,
                                       fcurve_pos_z)

                        location = None
                        for key_time_i, key_time in enumerate(streams[0]):
                            # print(' key_time: %s' % str(key_time[0]))
                            # keyframe = key_time_i * (key_time[0] * 10) ## TODO: Do proper timing...
                            keyframe = key_time_i + 1
                            scs_offset = _convert_utils.change_to_scs_xyz_coordinates(
                                custom_channels[channel_name][2][1]
                                [key_time_i], import_scale)
                            offset = Vector(scs_offset)
                            if location is None:
                                location = offset
                            else:
                                location = location + offset
                            # print(' > location: %s' % str(location))

                            # BUILD TRANSLATION CURVES
                            pos_fcurves[0].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[0],
                                options={'FAST'})
                            pos_fcurves[1].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[1],
                                options={'FAST'})
                            pos_fcurves[2].keyframe_points.insert(
                                frame=float(keyframe),
                                value=location[2],
                                options={'FAST'})

                        # SET LINEAR INTERPOLATION FOR ALL CURVES
                        for curve in pos_fcurves:
                            for keyframe in curve.keyframe_points:
                                keyframe.interpolation = 'LINEAR'
                    else:
                        lprint('W Unknown channel %r in "%s" file.',
                               (channel_name, os.path.basename(pia_filepath)))

                        # CREATE SCS ANIMATION
            animation = _animation_utils.add_animation_to_root(
                root_object, animation_name)
            animation.export = True
            animation.action = anim_action.name
            animation.anim_start = anim_action.frame_range[0]
            animation.anim_end = anim_action.frame_range[1]
            # animation.anim_export_step =
            # animation.anim_export_filepath =
            if total_time:
                animation.length = total_time

                # WARNING PRINTOUTS
                # if piece_count < 0: Print(dump_level, '\nW More Pieces found than were declared!')
                # if piece_count > 0: Print(dump_level, '\nW Some Pieces not found, but were declared!')
                # if dump_level > 1: print('')
        else:
            lprint('I    "%s" file REJECTED',
                   (os.path.basename(pia_filepath), ))

    print("************************************")
    return {'FINISHED'}
Example #8
0
def load(context, filepath):
    """

    :param context: Blender Context currently used for window_manager.update_progress and bpy_object_utils.object_data_add
    :type context: bpy.types.Context
    :param filepath: File path to be imported
    :type filepath: str
    :return: Return state statuses (Usually 'FINISHED')
    :rtype: dict
    """
    import time

    t = time.time()
    bpy.context.window.cursor_modal_set('WAIT')
    # import_scale = _get_scs_globals().import_scale
    # load_textures = _get_scs_globals().load_textures
    # mesh_creation_type = _get_scs_globals().mesh_creation_type
    scs_globals = _get_scs_globals()
    dump_level = int(scs_globals.dump_level)
    lprint("", report_errors=-1, report_warnings=-1
           )  # Clear the 'error_messages' and 'warning_messages'

    collision_locators = []
    prefab_locators = []
    loaded_variants = []
    objects = []
    skinned_objects = []
    locators = []
    mats_info = []
    scs_root_object = skeleton = bones = armature = None

    # ## NEW SCENE CREATION
    # if _get_scs_globals().scs_lod_definition_type == 'scenes':
    # if context.scene.name != 'Scene':
    # bpy.ops.scene.new(type='NEW')

    # IMPORT PIM
    if scs_globals.import_pim_file or scs_globals.import_pis_file:
        if filepath:
            if os.path.isfile(filepath):
                lprint('\nD PIM filepath:\n  %s',
                       (filepath.replace("\\", "/"), ))
                result, objects, skinned_objects, locators, armature, skeleton, mats_info = _pim.load(
                    context, filepath)
                # print('  armature:\n%s\n  skeleton:\n%s' % (str(armature), str(skeleton)))
            else:
                lprint('\nI No file found at %r!' %
                       (filepath.replace("\\", "/"), ))
        else:
            lprint('\nI No filepath provided!')

    # IMPORT PIT
    bpy.context.scene.objects.active = None
    if scs_globals.import_pit_file:
        pit_filepath = str(filepath[:-1] + 't')
        if os.path.isfile(pit_filepath):
            lprint('\nD PIT filepath:\n  %s', (pit_filepath, ))
            # print('PIT filepath:\n  %s' % pit_filepath)
            result, loaded_variants = _pit.load(pit_filepath, mats_info)
        else:
            lprint('\nI No PIT file.')
            # print('INFO - No PIT file.')

    # IMPORT PIC
    if scs_globals.import_pic_file:
        pic_filepath = str(filepath[:-1] + 'c')
        if os.path.isfile(pic_filepath):
            lprint('\nD PIC filepath:\n  %s', (pic_filepath, ))
            # print('PIC filepath:\n  %s' % pic_filepath)
            result, collision_locators = _pic.load(pic_filepath)
        else:
            lprint('\nI No PIC file.')
            # print('INFO - No PIC file.')

    # IMPORT PIP
    if scs_globals.import_pip_file:
        pip_filepath = str(filepath[:-1] + 'p')
        if os.path.isfile(pip_filepath):
            lprint('\nD PIP filepath:\n  %s', (pip_filepath, ))
            # print('PIP filepath:\n  %s' % pip_filepath)
            result, prefab_locators = _pip.load(pip_filepath)
        else:
            lprint('\nI No PIP file.')
            # print('INFO - No PIP file.')

    # SETUP 'SCS GAME OBJECTS'
    for item in collision_locators:
        locators.append(item)
    for item in prefab_locators:
        locators.append(item)
    path, file = os.path.split(filepath)
    # print('  path: %r\n  file: %r' % (path, file))
    lod_name, ext = os.path.splitext(file)
    if objects or locators or (armature and skeleton):
        scs_root_object = _create_scs_root_object(lod_name, loaded_variants,
                                                  objects, skinned_objects,
                                                  locators, armature)

    # IMPORT PIS
    if scs_globals.import_pis_file:
        pis_filepath = str(filepath[:-1] + 's')
        if os.path.isfile(pis_filepath):
            lprint('\nD PIS filepath:\n  %s', (pis_filepath, ))
            # print('PIS filepath:\n  %s' % pis_filepath)
            bones = _pis.load(pis_filepath, armature)
        else:
            bones = None
            lprint('\nI No PIS file.')
            # print('INFO - No PIS file.')

    # IMPORT PIA
    if scs_globals.import_pis_file and scs_globals.import_pia_file:
        basepath = os.path.dirname(filepath)
        # Search for PIA files in model's directory and its subdirectiories...
        lprint('\nD Searching the directory for PIA files:\n   %s',
               (basepath, ))
        # print('\nSearching the directory for PIA files:\n   %s' % str(basepath))
        pia_files = []
        index = 0
        for root, dirs, files in os.walk(basepath):
            if not scs_globals.include_subdirs_for_pia:
                if index > 0:
                    break
            # print('  root: %s - dirs: %s - files: %s' % (str(root), str(dirs), str(files)))
            for file in files:
                if file.endswith(".pia"):
                    pia_filepath = os.path.join(root, file)
                    pia_files.append(pia_filepath)
            index += 1

        if len(pia_files) > 0:
            lprint('D PIA files found:')
            for pia_filepath in pia_files:
                lprint('D %r', pia_filepath)
            # print('armature: %s\nskeleton: %r\nbones: %s\n' % (str(armature), str(skeleton), str(bones)))
            _pia.load(scs_root_object, pia_files, armature, skeleton, bones)
        else:
            lprint('\nI No PIA files.')

            # ## SETUP 'SCS GAME OBJECTS'
            # for item in collision_locators:
            # locators.append(item)
            # for item in prefab_locators:
            # locators.append(item)
            # path, file = os.path.split(filepath)
            # print('  path: %r\n  file: %r' % (path, file))
            # lod_name, ext = os.path.splitext(file)
            # if objects:
            # scs_root_object = create_scs_root_object(lod_name, loaded_variants, objects, skinned_objects, locators, armature)

            # SET OPTIMAL SETTINGS AND DRAW MODES

    # fix scene objects count so it won't trigger copy cycle
    bpy.context.scene.scs_cached_num_objects = len(bpy.context.scene.objects)

    # Turn on Textured Solid in 3D view...
    for bl_screen in bpy.data.screens:
        for bl_area in bl_screen.areas:
            for bl_space in bl_area.spaces:
                if bl_space.type == 'VIEW_3D':
                    bl_space.show_textured_solid = True

    # Turn on GLSL in 3D view...
    bpy.context.scene.game_settings.material_mode = 'GLSL'

    # Turn on "Frame Dropping" for animation playback...
    bpy.context.scene.use_frame_drop = True

    # FINAL FEEDBACK
    bpy.context.window.cursor_modal_restore()
    lprint('\nI Import compleeted in %.3f sec.',
           time.time() - t,
           report_errors=True,
           report_warnings=True)
    return True