Example #1
0
 def invoke(self, context, event):
     """Invoke a file path selector."""
     scs_project_path = _get_scs_globals().scs_project_path
     if scs_project_path not in self.directory:
         self.directory = _get_scs_globals().scs_project_path
     context.window_manager.fileselect_add(self)
     return {'RUNNING_MODAL'}
Example #2
0
def get_mesh(obj):
    """
    Returns Mesh data of provided Object (un)affected with specified Modifiers, which are
    evaluated as within provided Scene.
    :param obj:
    :return:
    """
    scene = bpy.context.scene
    disabled_modifiers = []

    if _get_scs_globals().output_type.startswith('def'):
        if _get_scs_globals().apply_modifiers:
            if _get_scs_globals().exclude_edgesplit:
                disabled_modifiers = disable_edgesplit(obj, modifier_to_disable='EDGE_SPLIT')
            mesh = obj.to_mesh(scene, True, 'PREVIEW')
        else:
            mesh = obj.data
    else:
        if _get_scs_globals().apply_modifiers:
            mesh = obj.to_mesh(scene, True, 'PREVIEW')
        else:
            if _get_scs_globals().include_edgesplit:
                disabled_modifiers = disable_edgesplit(obj, modifier_to_disable='EDGE_SPLIT', inverse=True)
                mesh = obj.to_mesh(scene, True, 'PREVIEW')
            else:
                disabled_modifiers = disable_edgesplit(obj, modifier_to_disable='ANY', inverse=True)
                mesh = obj.to_mesh(scene, True, 'PREVIEW')

    restore_modifiers(obj, disabled_modifiers)

    return mesh
Example #3
0
        def execute(self, context):

            main_path = _get_scs_globals().conv_hlpr_converters_path
            extra_mount_path = os.path.join(main_path, "extra_mount.txt")
            convert_cmd_path = os.path.join(main_path, "convert.cmd")

            if not os.path.isfile(extra_mount_path) or not os.path.isfile(convert_cmd_path):
                self.report({'ERROR'}, "Conversion tools path is incorrect! Please fix it first.")
                return {'CANCELLED'}

            with open(extra_mount_path, mode="w") as f:

                for path_entry in _get_scs_globals().conv_hlpr_custom_paths:

                    path = path_entry.path.rstrip(os.sep)

                    if not os.path.isdir(path):
                        self.report({'WARNING'}, "None existing custom paths detected, they were ignored!")
                        continue

                    f.write(path)
                    f.write("\r\n")

                if self.include_current_project:
                    f.write(os.path.realpath(_get_scs_globals().scs_project_path))

            return ConversionHelper.RunConversion.execute(self, context)
Example #4
0
        def invoke(self, context, event):
            """Invoke a file path selector."""
            filepath = getattr(bpy.context.active_object.active_material.scs_props, self.shader_texture)
            if filepath.startswith(str(os.sep + os.sep)) and os.path.isdir(_get_scs_globals().scs_project_path):
                self.filepath = os.path.join(_get_scs_globals().scs_project_path, _path_utils.strip_sep(filepath))
            elif os.path.isfile(filepath):
                self.filepath = filepath
            else:
                self.filepath = _get_scs_globals().scs_project_path

            context.window_manager.fileselect_add(self)
            return {'RUNNING_MODAL'}
Example #5
0
def initialise_scs_dict(scene):
    """Parts and Variants data initialisation (persistent).

    Things which this function does:
    1. copies all the settings to current world
    2. checks object identities
    3. updates shaders presets path and reloads them

    Cases when it should be run:
    1. Blender startup -> SCS tools needs to configured
    2. Opening .blend file -> because all the configs needs to be moved to current world
    3. addon reloading and enable/disable -> for SCS tools this is the same as opening Blender

    :param scene: Current Blender Scene
    :type scene: bpy.types.Scene
    """

    # SCREEN CHECK...
    if bpy.context.screen:
        lprint("I >Initialization of SCS scene")

        # NOTE: covers: start-up, reload, enable/disable and it should be immediately removed
        # from handlers as soon as it's executed for the first time
        if initialise_scs_dict in bpy.app.handlers.scene_update_post:
            lprint("I ---> Removing 'scene_update_post' handler...")
            bpy.app.handlers.scene_update_post.remove(initialise_scs_dict)

        # INITIALIZE CUSTOM CONNECTIONS DRAWING SYSTEM
        _connections_group_wrapper.init()

        # TRIGGER RELOAD OF CUSTOM ICONS
        _icons_wrapper.init()

        # USE SETTINGS FROM CONFIG...
        # NOTE: Reapplying the settings from config file to the currently opened Blender file datablock.
        # The thing is, that every Blend file holds its own copy of SCS Global Settings from the machine on which it got saved.
        # The SCS Global Settings needs to be overwritten upon each file load to reflect the settings from local config file,
        # but also upon every SCS Project Base Path change.
        _config_container.apply_settings()

        # GLOBAL PATH CHECK...
        if _get_scs_globals().scs_project_path != "":
            if not os.path.isdir(_get_scs_globals().scs_project_path):
                lprint("\nW The Project Path %r is NOT VALID!\n\tPLEASE SELECT A VALID PATH TO THE PROJECT BASE FOLDER.\n",
                       (_get_scs_globals().scs_project_path,))

        # CREATE PREVIEW MODEL LIBRARY
        _preview_models.init()

        # ADD DRAW HANDLERS
        _open_gl_callback.enable(mode=bpy.context.scene.scs_props.drawing_mode)
Example #6
0
        def execute(self, context):

            main_path = _get_scs_globals().conv_hlpr_converters_path
            extra_mount_path = os.path.join(main_path, "extra_mount.txt")
            convert_cmd_path = os.path.join(main_path, "convert.cmd")

            if not os.path.isfile(extra_mount_path) or not os.path.isfile(convert_cmd_path):
                self.report({'ERROR'}, "Conversion tools path is incorrect! Please fix it first.")
                return {'CANCELLED'}

            with open(extra_mount_path, mode="w") as f:
                f.write(os.path.realpath(_get_scs_globals().scs_project_path))

            return ConversionHelper.RunConversion.execute(self, context)
Example #7
0
def pre_save(scene):
    # remove custom icons from blender datablock
    icon_list = _ICONS_consts.Types.as_list()
    for icon in icon_list:
        if icon in bpy.data.images:
            img = bpy.data.images[icon]
            img.use_fake_user = False
            img.user_clear()

            bpy.data.images.remove(img)

    # clear all not needed inventories
    scs_globals = _get_scs_globals()
    scs_globals.scs_hookup_inventory.clear()
    scs_globals.scs_matsubs_inventory.clear()
    scs_globals.scs_sign_model_inventory.clear()
    scs_globals.scs_traffic_rules_inventory.clear()
    scs_globals.scs_tsem_profile_inventory.clear()

    # clear unused materials, this has to be done because of usage of same material inside nodes
    for material in bpy.data.materials:
        if material.node_tree and material.users == 1:
            for node in material.node_tree.nodes:
                if node.type in ("MATERIAL_EXT", "MATERIAL"):
                    if node.material == material:
                        material.user_clear()

    # make sure to save actions used in at least one scs game object
    for obj in bpy.data.objects:
        if obj.type == "EMPTY" and obj.scs_props.empty_object_type == "SCS_Root":
            for scs_anim in obj.scs_object_animation_inventory:
                if scs_anim.action in bpy.data.actions:
                    bpy.data.actions[scs_anim.action].use_fake_user = True
Example #8
0
def export(armature, bone_list, filepath, filename):
    """Exports PIA animation


    :param armature:
    :type armature:
    :param bone_list:
    :type bone_list:
    :param filepath: path to export
    :type filepath: str
    :param filename: name of exported file
    :type filename: str
    :return:
    :rtype:
    """
    scs_globals = _get_scs_globals()
    # anim_file_name = os.path.splitext(os.path.split(filepath)[1])[0]

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

    # DATA GATHERING
    skeleton_file = str(filename + ".pis")
    action = armature.animation_data.action
    total_time = action.scs_props.action_length
    anim_export_filepath = action.scs_props.anim_export_filepath
    bone_channels = _get_bone_channels(bone_list, action, scs_globals.export_scale)
    custom_channels = _get_custom_channels(action)

    # DATA CREATION
    header_section = _fill_header_section(action, scs_globals.sign_export)
    custom_channel_sections = _fill_channel_sections(custom_channels, "CustomChannel")
    bone_channel_sections = _fill_channel_sections(bone_channels, "BoneChannel")
    global_section = _fill_global_section(skeleton_file, total_time, len(bone_channels), len(custom_channels))

    # DATA ASSEMBLING
    pia_container = [header_section, global_section]
    for section in custom_channel_sections:
        pia_container.append(section)
    for section in bone_channel_sections:
        pia_container.append(section)

    # EXPORT PIA TO CUSTOM LOCATION
    # pia_filepath = str(filepath[:-1] + "a")
    dir_path = os.path.dirname(filepath)
    if anim_export_filepath:
        if os.path.isdir(anim_export_filepath):
            dir_path = anim_export_filepath
        else:
            pass  # TODO: Create location?

    # FILE EXPORT
    ind = "    "
    pia_filepath = os.path.join(dir_path, str(action.name + ".pia"))
    _pix_container.write_data_to_file(pia_container, pia_filepath, ind)

    # print("************************************")
    return {'FINISHED'}
Example #9
0
def pre_save(scene):
    # remove custom icons from blender datablock
    icon_list = _ICONS_consts.Types.as_list()
    for icon in icon_list:
        if icon in bpy.data.images:
            img = bpy.data.images[icon]
            img.use_fake_user = False
            img.user_clear()

            bpy.data.images.remove(img)

    # clear all not needed inventories
    scs_globals = _get_scs_globals()
    scs_globals.scs_hookup_inventory.clear()
    scs_globals.scs_matsubs_inventory.clear()
    scs_globals.scs_sign_model_inventory.clear()
    scs_globals.scs_traffic_rules_inventory.clear()
    scs_globals.scs_tsem_profile_inventory.clear()

    # clear unused materials, this has to be done because of usage of same material inside nodes
    for material in bpy.data.materials:
        if material.node_tree and material.users == 1:
            for node in material.node_tree.nodes:
                if node.type in ("MATERIAL_EXT", "MATERIAL"):
                    if node.material == material:
                        material.user_clear()
Example #10
0
def update_item_in_file(item_pointer, new_value):
    """Resaves config file with updated given item to a new value.
    The "item_pointer" variable must be in form of 'SectionName.PropertyName',
    example: 'Paths.ProjectPath'."""

    if _get_scs_globals().config_update_lock:
        return False
    else:
        filepath = get_config_filepath()
        ind = '    '
        config_container = _pix.get_data_from_file(filepath, ind)

        new_settings_container = []
        if config_container:

            new_value_changed = False
            item_pointer_split = item_pointer.split('.', 1)
            for section in config_container:

                new_section = _SectionData(section.type)
                for prop in section.props:
                    if section.type == item_pointer_split[0] and prop[0] == item_pointer_split[1]:
                        new_section.props.append((prop[0], new_value))
                        new_value_changed = True
                    else:
                        new_section.props.append((prop[0], prop[1]))

                # append new properties if they are not yet there
                if not new_value_changed and section.type == item_pointer_split[0]:
                    new_section.props.append((item_pointer_split[1], new_value))

                new_settings_container.append(new_section)

        write_file(new_settings_container, filepath, ind)
    return True
Example #11
0
def get_skeleton_relative_filepath(armature, directory, default_name):
    """Get's skeleton relative path to given directory. This path can be used for linking
    skeletons in PIM and PIA files.

    :param armature: armature object which will be used as scs skeleton
    :type armature: bpy.types.Object
    :param directory: directory from which relative path of skeleton should be gotten
    :type directory: str
    :param default_name: if custom path is empty this name will be used as the name of pis file
    :type default_name: str
    :return: relative path to predicted PIS file of given armature
    :rtype: str
    """

    skeleton_custom_dir = armature.scs_props.scs_skeleton_custom_export_dirpath
    skeleton_custom_name = armature.scs_props.scs_skeleton_custom_name

    skeleton_path = ""
    if skeleton_custom_dir != "":
        if skeleton_custom_dir.startswith("//"):
            skeleton_path = os.path.relpath(os.path.join(_get_scs_globals().scs_project_path, skeleton_custom_dir[2:]), directory)
        else:
            lprint("E Custom skeleton export path is not relative to SCS Project Base Path.\n\t   " +
                   "Custom path will be ignored, which might lead to wrongly linked skeleton file inside PIM and PIA files.")

    skeleton_name = (skeleton_custom_name if skeleton_custom_name != "" else default_name) + ".pis"

    return os.path.join(skeleton_path, skeleton_name)
Example #12
0
def get_scs_texture_str(texture_string):
    """Get texture string as presented in SCS files: "/material/environment/vehicle_reflection"
    without any file extensions. Input path can also have texture object extension or supported images extensions.
    Path will be searched and returned in this order:
    1. relative path on current SCS Project Base Path
    2. relative path on parent base dirs of current SCS Project Base Path in the case of mod/dlc
    3. find absolute file path
    4. return unchanged texture string path

    :param texture_string: texture string for which texture should be found e.g.: "/material/environment/vehicle_reflection"
    :type texture_string: str
    :return: relative path to texture object or absolute path to texture object or uncanged texture string
    :rtype: str
    """

    scs_project_path = _get_scs_globals().scs_project_path
    orig_texture_string = texture_string

    # remove any directory separators left overs from different platform
    texture_string = texture_string.replace("/", os.sep).replace("\\", os.sep)

    extensions, texture_string = get_texture_extens_and_strip_path(texture_string)

    # if texture string starts with scs project path we can directly strip of project path
    if startswith(texture_string, scs_project_path):
        texture_string = texture_string[len(scs_project_path):]
    else:  # check if texture string came from base project while scs project path is in dlc/mod folder

        # first find longest matching path
        i = 1
        while startswith(scs_project_path, texture_string[:i]) and i < len(texture_string):
            i += 1

        # now check if provided texture string is the same as:
        # current scs project path + one or two directories up + non matched path of the part
        for infix in ("..", ".." + os.sep + ".."):

            nonmatched_path_part = texture_string[i - 2:]

            modif_texture_string = os.path.join(scs_project_path, infix + nonmatched_path_part)
            # if one or two directories up is the same path as texture string
            # and non matched path part is starting with /base we got a hit:
            # resulting relative path is non matched path part with stripped "/base" start
            if is_samepath(modif_texture_string, texture_string) and startswith(nonmatched_path_part, os.sep + "base"):
                texture_string = nonmatched_path_part[5:]
                break

    # check for relative TOBJ, TGA, PNG
    for ext in extensions:
        texture_path = get_abs_path("//" + texture_string.strip(os.sep) + ext)
        if texture_path and os.path.isfile(texture_path):
            return "//" + texture_string.replace(os.sep, "/").strip("/") + ext

    # check for absolute TOBJ, TGA, PNG
    for ext in extensions:
        texture_path = get_abs_path(texture_string + ext, skip_mod_check=True)
        if texture_path and os.path.isfile(texture_path):
            return texture_string.replace(os.sep, "/") + ext

    return orig_texture_string
Example #13
0
def post_save(scene):
    # reload inventories
    readonly = True
    scs_globals = _get_scs_globals()
    _config_container.update_hookup_library_rel_path(
        scs_globals.scs_hookup_inventory,
        scs_globals.hookup_library_rel_path,
        readonly
    )
    _config_container.update_matsubs_inventory(
        scs_globals.scs_matsubs_inventory,
        scs_globals.matsubs_library_rel_path,
        readonly
    )
    _config_container.update_traffic_rules_library_rel_path(
        scs_globals.scs_traffic_rules_inventory,
        scs_globals.traffic_rules_library_rel_path,
        readonly
    )
    _config_container.update_tsem_library_rel_path(
        scs_globals.scs_tsem_profile_inventory,
        scs_globals.tsem_library_rel_path,
        readonly
    )
    _config_container.update_sign_library_rel_path(
        scs_globals.scs_sign_model_inventory,
        scs_globals.sign_library_rel_path,
        readonly
    )
Example #14
0
def get_abs_path(path_in, subdir_path=''):
    """Takes a path, which can be either absolute or relative to the 'SCS Project Base Path'.
    If the path is existing and valid, it returns the absolute path, otherwise None.
    Optionally a subdir_path can be provided, which will be added to the 'SCS Project Base Path'.

    :param path_in: Absolute or relative path to current 'SCS Project Base path'
    :type path_in: str
    :param subdir_path: Additional subdirs can be provided, they will be added to the 'SCS Project Base Path'
    :type subdir_path: str
    :return: Absolute path or None
    :rtype: str
    """
    root_path = _get_scs_globals().scs_project_path
    if subdir_path != '':
        root_path = os.path.join(root_path, subdir_path)

    if path_in.startswith("//"):
        if len(root_path) > 2:
            result = os.path.join(root_path, path_in[2:])
        else:
            result = None
    else:
        result = path_in

    return result
Example #15
0
def export(scs_root_obj, armature, scs_animation, dirpath, skeleton_filepath):
    """Exports PIA animation

    :param scs_root_obj: root object of current animation
    :type scs_root_obj: bpy.types.Object
    :param armature: armature object of current animation
    :type armature: bpy.types.Object
    :param scs_animation: animation which should get exported
    :type scs_animation: io_scs_tools.properties.object.ObjectAnimationInventory
    :param dirpath: path to export
    :type dirpath: str
    :param skeleton_filepath: name of skeleton file that this animation works on
    :type skeleton_filepath: str
    """

    # safety checks
    if scs_animation.action not in bpy.data.actions:
        lprint(str("E Action %r requested by %r animation doesn't exists. Animation won't be exported!\n\t   "
                   "Make sure proper action is assigned to SCS Animation."),
               (scs_animation.action, scs_animation.name))
        return False

    scs_globals = _get_scs_globals()
    print("\n************************************")
    print("**      SCS PIA Exporter          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    # DATA GATHERING
    total_time = scs_animation.length
    action = bpy.data.actions[scs_animation.action]
    bone_channels = _get_bone_channels(scs_root_obj, armature, scs_animation, action, scs_globals.export_scale)
    custom_channels = _get_custom_channels(scs_animation, action)

    # DATA CREATION
    header_section = _fill_header_section(scs_animation.name, scs_globals.sign_export)
    custom_channel_sections = _fill_channel_sections(custom_channels, "CustomChannel")
    bone_channel_sections = _fill_channel_sections(bone_channels, "BoneChannel")
    global_section = _fill_global_section(skeleton_filepath, total_time, len(bone_channels), len(custom_channels))

    # post creation safety checks
    if len(bone_channels) + len(custom_channels) == 0:
        lprint(str("E PIA file won't be exported, as SCS Animation %r\n\t   "
                   "doesn't effect armature or it's bones or data are invalid."),
               (scs_animation.name,))
        return False

    # DATA ASSEMBLING
    pia_container = [header_section, global_section]
    for section in custom_channel_sections:
        pia_container.append(section)
    for section in bone_channel_sections:
        pia_container.append(section)

    # FILE EXPORT
    ind = "    "
    filepath = os.path.join(dirpath, scs_animation.name + ".pia")

    # print("************************************")
    return _pix_container.write_data_to_file(pia_container, filepath, ind)
Example #16
0
        def execute_export(self, context, disable_local_view):
            """Actually executes export of current selected objects (bpy.context.selected_objects)

            :param context: operator context
            :type context: bpy_struct
            :param disable_local_view: True if you want to disable local view after export
            :type disable_local_view: bool
            :return: succes of batch export
            :rtype: {'FINISHED'} | {'CANCELLED'}
            """
            _get_scs_globals().content_type = 'selection'  # NOTE: I'm not sure if this is still necessary.

            try:
                result = _export.batch_export(self, tuple(bpy.context.selected_objects), exclude_switched_off=False)
            except Exception as e:

                result = {"CANCELLED"}
                context.window.cursor_modal_restore()

                import traceback

                traceback.print_exc()
                lprint("E Unexpected %r accured during batch export, see stack trace above.",
                       (type(e).__name__,),
                       report_errors=1,
                       report_warnings=1)

            if disable_local_view:
                _view3d_utils.switch_local_view(False)

            return result
Example #17
0
    def get_tobj_filepath(texture_data_value):
        # print(' texture_data_value: %r' % texture_data_value)
        if texture_data_value != '':

            # exception for Windows so os.path.join can correctly join paths
            texture_data_value = texture_data_value.replace("/", os.sep)

            base_path = _get_scs_globals().scs_project_path
            if os.path.isdir(base_path):
                # print(' base_path: %r' % base_path)
                head, tail = os.path.split(texture_data_value)
                if head.startswith(os.sep):
                    head = head[1:]
                    # print(' head: %r' % head)
                tobj_path = os.path.join(base_path, head)
                # print(' tobj_path: %r' % tobj_path)
                tobj_name = str(tail + ".tobj")
                # print(' tobj_name: %r' % tobj_name)
                tobj_path = os.path.join(tobj_path, tobj_name)
                # print(' tobj_filepath: %r' % tobj_filepath)
                if os.path.isfile(tobj_path):
                    return tobj_path
                else:
                    lprint("E Texture file %r not found!", (tobj_path,))
            else:
                lprint("E No 'base' directory!")
        return None
Example #18
0
    def draw(self, context):
        """UI draw function."""
        layout = self.layout
        scene = context.scene
        # print('scene: %r\t- %r' % (scene.name, context.scene.name))
        # obj = context.object  # FIXME: Gives 'None type' in this place - everywhere else it works normally (?!?)
        # print('obj:   %s\t- %s' % (obj, context.object))
        # blend_data = context.blend_data
        scs_globals = _get_scs_globals()

        # def draw_scs_tools_settings_panel_box(layout):
        # """Draw SCS Tools settings panel box."""
        # layout_box = layout.box()
        # layout_box_row = layout_box.row()
        # layout_box_row.prop(scene.scs_props, 'scs_lod_definition_type', icon='NONE', expand=True)
        # layout_box_row.prop(scs_globals, 'scs_lod_definition_type', icon='NONE', expand=True)

        if scene:
            # PART PANEL
            # if obj:  # FIXME: 'None type' obj - see above...
            # ui.shared.draw_part_panel(layout, scene, obj)

            # GLOBAL SETTINGS PANEL
            _draw_global_settings_panel(scene, layout, scs_globals)

            # EXPORT PANEL
            if context.mode == 'OBJECT':
                _draw_export_panel(scene, layout, scs_globals)
Example #19
0
        def execute(self, context):

            scs_globals = _get_scs_globals()

            if self.type == "DefaultExportPath":
                obj = context.scene.scs_props
                prop = "default_export_filepath"
            elif self.type == "GameObjectExportPath":
                obj = context.active_object.scs_props
                prop = "scs_root_object_export_filepath"
            elif self.type == "GameObjectAnimExportPath":
                obj = _object_utils.get_scs_root(context.active_object).scs_props
                prop = "scs_root_object_anim_export_filepath"
            else:
                obj = context.active_object.scs_props
                prop = "scs_skeleton_custom_export_dirpath"

            if _path_utils.startswith(self.directory, scs_globals.scs_project_path):
                setattr(obj, prop, _path_utils.relative_path(scs_globals.scs_project_path, self.directory))
            else:
                setattr(obj, prop, "//")
                self.report({'ERROR'}, "Selected path is not within SCS Project Base Path,\npath will be reset to SCS Project Base Path instead.")
                return {'CANCELLED'}

            return {'FINISHED'}
Example #20
0
def get_animations_relative_filepath(scs_root, directory):
    """Get's skeleton relative path to given directory. This path can be used for linking
    skeletons in PIM and PIA files.

    :param scs_root: scs root object of this animation
    :type scs_root: bpy.types.Object
    :param directory: directory from which relative path of animaton should be gotten
    :type directory: str
    :return: relative path to predicted PIS file of given armature
    :rtype: str
    """

    anims_path = ""

    if scs_root.scs_props.scs_root_object_allow_anim_custom_path:
        animations_custom_dir = scs_root.scs_props.scs_root_object_anim_export_filepath

        if animations_custom_dir != "":

            if animations_custom_dir.startswith("//"):
                anims_path = os.path.relpath(os.path.join(_get_scs_globals().scs_project_path, animations_custom_dir[2:]), directory)
            else:
                return None

    return anims_path
Example #21
0
def export(bone_list, filepath, filename):
    scs_globals = _get_scs_globals()

    print("\n************************************")
    print("**      SCS PIS Exporter          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    # DATA GATHERING
    # bone_list = []

    # BONES...
    # TODO: SORT "bone_list"...

    # DATA CREATION
    header_section = _fill_header_section(filename, scs_globals.sign_export)
    bones_section = _fill_bones_sections(bone_list, scs_globals.export_scale)
    global_section = _fill_global_section(len(bone_list))

    # DATA ASSEMBLING
    pis_container = [header_section, global_section, bones_section]

    # FILE EXPORT
    ind = "    "
    pis_filepath = str(filepath + ".pis")
    result = _pix_container.write_data_to_file(pis_container, pis_filepath, ind)

    # print("************************************")
    return result
Example #22
0
def draw(visible_loc_names):
    """Draws navigation curves, map lines and trigger lines from given dictionary of
    locator names as keys.

    :param visible_loc_names: dictionary of visible prefab locators names
    :type visible_loc_names: dict
    """

    scs_globals = _get_scs_globals()

    if _execute_draw(scs_globals.optimized_connections_drawing):

        connections = bpy.data.groups[_GROUP_NAME][_core.MAIN_DICT][_core.REFS][_core.CONNECTIONS][_core.ENTRIES]

        # gets visible connections and draw them
        conns_to_draw = _core.gather_connections_upon_selected(bpy.data.groups[_GROUP_NAME], visible_loc_names)
        for conn_key in conns_to_draw.keys():

            conn_entry = connections[conn_key]

            locator_type = bpy.data.objects[conn_entry[_core.IN]].scs_props.locator_prefab_type
            if locator_type == "Navigation Point":
                _gl_primitive.draw_shape_curve(conn_entry[_core.DATA], not conn_entry[_core.VALID], scs_globals)
            else:
                _gl_primitive.draw_shape_line(conn_entry[_core.DATA], not conn_entry[_core.VALID], locator_type == "Map Point", scs_globals)
Example #23
0
        def execute(self, context):

            main_path = _get_scs_globals().conv_hlpr_converters_path

            system_type = platform.system()

            if system_type == "Linux":

                if os.system("command -v wineconsole") == 0:
                    command = ["wineconsole " + os.path.join(main_path, "convert.cmd")]
                else:
                    self.report({'ERROR'}, "Conversion aborted! Please install WINE, it's required to run conversion tools on Linux!")
                    return {'CANCELLED'}

            elif system_type == "Windows":

                command = 'cmd /C ""' + os.path.join(main_path, "convert.cmd") + '""'
                command = command.replace("\\", "/")

            else:

                self.report({'ERROR'}, "Unsupported OS type! Make sure you are running either Linux or Windows!")
                return {'CANCELLED'}

            # try to run conversion tools
            if subprocess.call(command, shell=True) == 0:
                self.report({'INFO'}, "Conversion done!")
            else:
                self.report({'ERROR'}, "Can't run conversion tools or there were errors by converting!")

            return {'FINISHED'}
Example #24
0
    def check(self, context):

        if self.scs_project_path_mode:
            _get_scs_globals().scs_project_path = os.path.dirname(self.filepath)
            self.scs_project_path_mode = False

        return True
Example #25
0
def export(collision_locator_list, filepath, filename, used_parts):
    """Exports PIC colliders

    :param collision_locator_list:
    :type collision_locator_list:
    :param filepath:
    :type filepath:
    :param filename:
    :type filename:
    :param used_parts: dictionary of used parts for current game object (it will get extended if some part from pic is not yet in)
    :type: dict
    :return:
    :rtype:
    """
    # scene = context.scene
    scs_globals = _get_scs_globals()
    # output_type = scs_globals.output_type  # TODO: UNUSED!

    print("\n************************************")
    print("**      SCS PIC Exporter          **")
    print("**      (c)2014 SCS Software      **")
    print("************************************\n")

    # DATA CREATION
    header_section = _fill_header_section(filename, scs_globals.sign_export)
    piece_sections = []
    materials = 0
    len_vertices = 0
    len_faces = 0
    convex_coll_locators = [loc for loc in collision_locator_list if loc.scs_props.locator_collider_type == "Convex"]
    if convex_coll_locators:
        len_vertices, len_faces, piece_sections = _fill_piece_sections(convex_coll_locators, scs_globals.export_scale)
        materials += 1
    part_sections = _fill_part_sections(collision_locator_list, used_parts)
    collision_locator_sections = _fill_collision_locator_sections(collision_locator_list)
    global_section = _fill_global_section(len_vertices, len_faces, materials,
                                          len(piece_sections), len(part_sections), len(collision_locator_sections))

    # DATA ASSEMBLING
    pic_container = [header_section, global_section]
    if convex_coll_locators:
        material_section = _fill_coll_material_section()
        pic_container.append(material_section)
    if piece_sections:
        for section in piece_sections:
            pic_container.append(section)
    for section in part_sections:
        pic_container.append(section)
    for section in collision_locator_sections:
        pic_container.append(section)
    # print('  pic_container:\n%s' % str(pic_container))

    # FILE EXPORT
    ind = "    "
    pic_filepath = str(filepath + ".pic")
    result = _pix_container.write_data_to_file(pic_container, pic_filepath, ind)

    # print("************************************")
    return result
Example #26
0
 def execute(self, context):
     """Set Shader Presets library file path."""
     scs_globals = _get_scs_globals()
     if self.rel_path:
         scs_globals.shader_presets_filepath = _path_utils.relative_path(scs_globals.scs_project_path, self.filepath)
     else:
         scs_globals.shader_presets_filepath = str(self.filepath)
     return {'FINISHED'}
Example #27
0
        def execute(self, context):
            """Set Material Substance library filepath."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath, scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(scs_globals.scs_project_path, self.filepath)

            scs_globals.matsubs_library_rel_path = self.filepath
            return {'FINISHED'}
Example #28
0
        def execute(self, context):
            """Set Traffic Rules library filepath."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath, scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(scs_globals.scs_project_path, self.filepath)

            scs_globals.traffic_rules_library_rel_path = self.filepath
            return {'FINISHED'}
Example #29
0
        def execute(self, context):
            """Set Sign directory path."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.filepath, scs_globals.scs_project_path):
                self.filepath = _path_utils.relative_path(scs_globals.scs_project_path, self.filepath)

            scs_globals.sign_library_rel_path = self.filepath
            return {'FINISHED'}
Example #30
0
        def execute(self, context):
            """Set Hookup directory path."""
            scs_globals = _get_scs_globals()

            if _path_utils.startswith(self.directory, scs_globals.scs_project_path):
                self.directory = _path_utils.relative_path(scs_globals.scs_project_path, self.directory)

            scs_globals.hookup_library_rel_path = self.directory
            return {'FINISHED'}
Example #31
0
def is_valid_matsubs_library_rel_path():
    """It returns True if there is valid "*.db" file in
    the Material Substance Library directory, otherwise False."""
    matsubs_library_abs_path = get_abs_path(
        _get_scs_globals().matsubs_library_rel_path)
    # print(' matsubs_library_abs_path: %r' % str(matsubs_library_abs_path))
    if matsubs_library_abs_path:
        if os.path.isfile(matsubs_library_abs_path):
            return True
        else:
            return False
    else:
        return False
Example #32
0
def is_valid_hookup_library_rel_path():
    """It returns True if there is at least one "*.sii" file in
    the resulting CgFX Library directory, otherwise False."""
    hookup_library_abs_path = get_abs_path(
        _get_scs_globals().hookup_library_rel_path, is_dir=True)
    if hookup_library_abs_path:
        for root, dirs, files in os.walk(hookup_library_abs_path):
            for file in files:
                if file.endswith(".sii"):
                    return True
            return False
    else:
        return False
Example #33
0
def is_valid_sun_profiles_library_path():
    """It returns True if there is valid "*.sii" file in
    the Sun Profiles Library directory, otherwise False."""
    sun_profiles_lib_path = get_abs_path(
        _get_scs_globals().sun_profiles_lib_path)

    if sun_profiles_lib_path:
        if os.path.isfile(sun_profiles_lib_path):
            return True
        else:
            return False
    else:
        return False
Example #34
0
    def draw(self, context):
        layout = self.get_layout()
        scs_globals = _get_scs_globals()

        layout.use_property_split = True
        layout.use_property_decorate = False
        layout.enabled = scs_globals.display_connections and not scs_globals.config_update_lock

        layout.prop(scs_globals, 'optimized_connections_drawing')
        layout.prop(scs_globals, 'curve_segments')
        layout.prop(scs_globals, 'np_connection_base_color')
        layout.prop(scs_globals, 'mp_connection_base_color')
        layout.prop(scs_globals, 'tp_connection_base_color')
Example #35
0
def get_abs_paths(filepath, is_dir=False, include_nonexist_alternative_bases=False, use_infixed_search=False):
    """Gets existing absolute paths to the "SCS Project Base Path" including searching for "base" folder
    one and two levels higher in filesystem hierachy.

    :param filepath: relative or absolute filepath
    :type filepath: str
    :param is_dir: flag specifying if given path should be directory
    :type is_dir: bool
    :param include_nonexist_alternative_bases: flag specifying if none existing absolute filepaths from alternative bases should be included in result
    :type include_nonexist_alternative_bases: bool
    :param use_infixed_search: search also for infixed filepaths? Meant for infixed library SII file searching eg. sign.dlc_north.sii
    :type use_infixed_search: bool
    :return: list of absolute paths or empty list if path not found
    :rtype: list[str]
    """

    abs_paths = {}
    """
    Store paths in dictionary to easily filter out duplicated paths.
    So make sure to use normalized paths as keys and actual paths as values which should be returned as result.
    """

    existance_check = os.path.isdir if is_dir else os.path.isfile

    for i, sub_dir in enumerate(("", "../base", "../../base")):

        # only search for additional absolute paths if usage of alternative bases isn't switched off by user
        if i > 0 and not _get_scs_globals().use_alternative_bases:
            continue

        # additionally search for infixed files (eg. sign.dlc_north.sii)
        if use_infixed_search:
            infixed_files = get_all_infixed_file_paths(get_abs_path(filepath, subdir_path=sub_dir, is_dir=is_dir, skip_mod_check=True))
        else:
            infixed_files = [get_abs_path(filepath, subdir_path=sub_dir, is_dir=is_dir, skip_mod_check=True)]

        for resulted_path in infixed_files:

            # ignore not found paths
            if resulted_path is None:
                continue

            # create normalized path to properly gather only unique paths
            normalized_resulted_path = full_norm(resulted_path)
            if (include_nonexist_alternative_bases or existance_check(resulted_path)) and normalized_resulted_path not in abs_paths:
                abs_paths[normalized_resulted_path] = resulted_path

    # we are returning de-normalized paths, as they might be used in printout and precious information
    # about origin of the path can be lost. (Eg. library was found in parent "base" directory,
    # but if we return normalized path this information will be lost)
    return abs_paths.values()
Example #36
0
    def finish(self):
        """Finish routine to restore objects & scene state after export.

        NOTE: Should be called after export has completed.
        """
        _get_scs_globals().preview_export_selection_active = False

        for obj, state in self.objects_states.items():
            obj.hide_viewport = state

        # recover old active scene and remove temporary one
        bpy.context.window.scene = self.active_scene
        bpy.data.scenes.remove(self.scene)
        self.scene = None
Example #37
0
def is_valid_shader_presets_library_path():
    """It returns True if there is valid "*.txt" file in
    the Shader Presets Library directory, otherwise False."""
    shader_presets_filepath = _get_scs_globals().shader_presets_filepath
    if shader_presets_filepath != "":
        if shader_presets_filepath.startswith("//"):  # RELATIVE PATH
            shader_presets_abs_path = get_abs_path(shader_presets_filepath)
            if shader_presets_abs_path:
                if os.path.isfile(shader_presets_abs_path):
                    return True
        else:  # ABSOLUTE PATH
            if os.path.isfile(shader_presets_filepath):
                return True
    return False
Example #38
0
def update_sign_library_rel_path(scs_sign_model_inventory, sign_library_rel_path, readonly=False):
    """The function deletes and populates again a list of Sign names in inventory. It also updates corresponding record in config file.

    :param sign_library_rel_path: Relative path to the directory with Sign files
    :type sign_library_rel_path: str
    """
    sign_library_filepath = _path_utils.get_abs_path(sign_library_rel_path)
    if sign_library_filepath:

        if _get_scs_globals().sign_library_use_infixed:
            sign_library_filepaths = _path_utils.get_all_infixed_file_paths(sign_library_filepath)
        else:
            sign_library_filepaths = [sign_library_filepath]

        # CLEAR INVENTORY
        scs_sign_model_inventory.clear()

        for sign_library_filepath in sign_library_filepaths:

            sign_container = _sii.get_data_from_file(sign_library_filepath)
            if sign_container:

                # ADD ALL ITEMS FROM CONTAINER INTO INVENTORY
                for item in sign_container:
                    if item.type == 'sign_model':
                        if item.id.startswith('sign.'):
                            if 'sign_name' in item.props:
                                sign_name = item.props['sign_name']
                            else:
                                continue

                            sign_item = scs_sign_model_inventory.add()
                            sign_item.name = sign_name + " : " + item.id[5:]
                            sign_item.item_id = item.id[5:]

                            if 'model_desc' in item.props:
                                sign_item.model_desc = item.props['model_desc']

                            if 'look_name' in item.props:
                                sign_item.look_name = item.props['look_name']

                            if 'category' in item.props:
                                sign_item.category = item.props['category']

                            if 'dynamic' in item.props:
                                if item.props['dynamic'] == 'true':
                                    sign_item.dynamic = True

    if not readonly:
        update_item_in_file('Paths.SignRelFilePath', sign_library_rel_path)
Example #39
0
def draw_common_settings(layout, log_level_only=False):
    """Draw common settings panel featuring log level and usage type of global settings if requested

    :param layout: Blender UI layout to draw operator to
    :type layout: UILayout
    :param log_level_only: draw only log level option
    :type log_level_only: bool
    """
    box4 = layout.box().column()

    if not log_level_only:
        row = box4.row(align=True)
        row.operator("scene.scs_copy_log", icon="COPYDOWN")

    row = box4.row(align=True)
    row.prop(_get_scs_globals(),
             'dump_level',
             text="Log Level",
             icon='MOD_EXPLODE')

    if not log_level_only:
        row = box4.row(align=True)
        row.prop(_get_scs_globals(), 'config_storage_place', icon='NONE')
Example #40
0
    def draw(self, context):
        """UI draw function."""
        layout = self.layout
        scene = bpy.context.scene
        mat = context.material
        # actual_look = _utils.get_actual_look()
        scs_globals = _get_scs_globals()

        if mat:
            layout_box = layout.box()

            # PROVISIONAL SHADER PRESET PANEL
            _draw_preset_shader_panel(layout_box, mat, scene.scs_props,
                                      scs_globals)
Example #41
0
    def execute(self, context):
        paths = [os.path.join(self.directory, name.name) for name in self.files]
        if not paths:
            paths.append(self.path)

        failed_files = []
        for self.filepath in paths:

            result = False
            if self.filepath.endswith("pim"):

                try:

                    _get_scs_globals().import_in_progress = True
                    result = _pix_import.load(context, self.filepath)
                    _get_scs_globals().import_in_progress = False

                except Exception as e:

                    _get_scs_globals().import_in_progress = False
                    context.window.cursor_modal_restore()

                    traceback.print_exc()
                    lprint("E Unexpected %r accured during import, see stack trace above.", (type(e).__name__,))

            if result is False:
                failed_files.append(str(self.filepath).replace("\\", "/"))

        if len(failed_files) > 0:
            err_message = "E Following files failed to load:\n"

            for _ in failed_files:
                err_message += "-> %r\n"

            lprint(err_message, tuple(failed_files), report_warnings=1, report_errors=1)

        return {'FINISHED'}
Example #42
0
def switch_local_view(show):
    """Switches first space in VIEW_3D areas to local or switches back to normal

    :param show: True if local view should be shown; False for switching back to normal view
    :type show: bool
    """
    for area in bpy.context.screen.areas:
        if area.type == 'VIEW_3D':
            if show and area.spaces[0].local_view is None:
                lprint("D Going into local view!")
                override = {
                    'window': bpy.context.window,
                    'screen': bpy.context.screen,
                    'blend_data': bpy.context.blend_data,
                    'scene': bpy.context.scene,
                    'region': area.regions[4],
                    'area': area
                }
                bpy.ops.view3d.localview(override)
            elif not show and area.spaces[0].local_view is not None:
                lprint("D Returning from local view!")
                override = {
                    'window': bpy.context.window,
                    'screen': bpy.context.screen,
                    'blend_data': bpy.context.blend_data,
                    'scene': bpy.context.scene,
                    'region': area.regions[4],
                    'area': area
                }
                bpy.ops.view3d.localview(override)

    if _get_scs_globals().preview_export_selection_active != show:
        _get_scs_globals().preview_export_selection_active = show
        # redraw properties panels because of preview property change
        for area in bpy.context.screen.areas:
            if area.type == "PROPERTIES":
                area.tag_redraw()
Example #43
0
    def set_shader_presets_item(self, value):
        """
        Receives an actual index of currently selected Shader preset name in the menu,
        sets that Shader name as active in active Material.
        :param value:
        :return:
        """

        material = bpy.context.active_object.active_material
        if value == 0:  # No Shader...
            material.scs_props.active_shader_preset_name = "<none>"
            material.scs_props.mat_effect_name = "None"
            material["scs_shader_attributes"] = {}
        else:
            for preset_i, preset in enumerate(
                    bpy.data.worlds[0].scs_shader_presets_inventory):
                if value == preset_i:

                    # Set Shader Preset in the Material
                    preset_section = _material_utils.get_shader_preset(
                        _get_scs_globals().shader_presets_filepath,
                        preset.name)

                    if preset_section:
                        preset_name = preset_section.get_prop_value(
                            "PresetName")
                        preset_effect = preset_section.get_prop_value("Effect")
                        material.scs_props.mat_effect_name = preset_effect

                        if preset_name:
                            _material_utils.set_shader_data_to_material(
                                material, preset_section, preset_effect)
                            material.scs_props.active_shader_preset_name = preset_name
                        else:
                            material.scs_props.active_shader_preset_name = "<none>"
                            material["scs_shader_attributes"] = {}
                            print('    NO "preset_name"!')
                            # if preset_effect:
                            # print('      preset_effect: "%s"' % preset_effect)
                            # if preset_flags:
                            # print('      preset_flags: "%s"' % preset_flags)
                            # if preset_attribute_cnt:
                            # print('      preset_attribute_cnt: "%s"' % preset_attribute_cnt)
                            # if preset_texture_cnt:
                            # print('      preset_texture_cnt: "%s"' % preset_texture_cnt)
                    else:
                        print('''NO "preset_section"! (Shouldn't happen!)''')
                else:
                    preset.active = False
Example #44
0
def _find_preset(presets_container, material_effect, material_textures):
    """Tries to find suitable Shader Preset (as defined in shader_presets.txt file) for imported shader. If it cannot be found, it will return None.

    :param presets_container: preset container in which preset shall be searched for; if none presets are readed from file
    :type presets_container: io_scs_tools.internals.structure.SectionData | None
    :param material_effect: Name of the requested Look
    :type material_effect: str
    :param material_textures: material textures dictionary (key: tex_id, value: tex_path)
    :type material_textures: dict
    :return: Preset index and name or None
    :rtype: (int, str) | None
    """

    scs_shader_presets_inventory = bpy.data.worlds[
        0].scs_shader_presets_inventory
    for i, shader_preset in enumerate(scs_shader_presets_inventory):

        if shader_preset.name != "<none>":
            preset_section = _material_utils.get_shader_preset(
                _get_scs_globals().shader_presets_filepath, shader_preset.name,
                presets_container)
            for preset_prop in preset_section.props:
                if preset_prop[0] == "Effect":

                    if preset_prop[1] == material_effect:

                        # also check for matching among locked textures
                        # NOTE: this check is needed because of possible multiple
                        # presets with the same effect name and different locked texture
                        matched_textures = 0
                        matched_textures_avaliable = 0
                        for tex_sec in preset_section.get_sections("Texture"):

                            tex_id = tex_sec.get_prop("Tag")[1]
                            tex_path = tex_sec.get_prop("Value")[1]
                            tex_lock = tex_sec.get_prop("Lock")

                            if tex_lock and tex_lock[1] == "True":
                                matched_textures_avaliable += 1

                                if tex_id in material_textures and (
                                        tex_path == material_textures[tex_id]
                                        or tex_path == ""):
                                    matched_textures += 1

                        if matched_textures == matched_textures_avaliable or matched_textures_avaliable == 0:
                            return i, shader_preset.name, preset_section

    return None, None, None
Example #45
0
    def draw(self, context):
        """UI draw function."""
        layout = self.layout
        scene = bpy.context.scene
        mat = context.material
        scs_globals = _get_scs_globals()

        if mat:
            # PROVISIONAL SHADER PRESET PANEL
            _draw_preset_shader_panel(layout.box(), mat, scene.scs_props, scs_globals)

            active_object = context.active_object
            scs_root_object = _object_utils.get_scs_root(active_object)
            if active_object and scs_root_object:
                _shared.draw_scs_looks_panel(layout, scene, active_object, scs_root_object)
Example #46
0
def convert_location_to_scs(location, offset_matrix=Matrix()):
    """Takes a vector or list of three floats and returns its coordinates transposed for SCS game engine.
    \rIf an "offset_matrix" is provided it is used to offset coordinates.

    :param location: Location (or three floats)
    :type location: Vector | list | tuple
    :param offset_matrix: Offset
    :type offset_matrix: Matrix
    :return: Transposed location
    :rtype: Vector
    """
    scs_globals = _get_scs_globals()
    return Matrix.Scale(scs_globals.export_scale,
                        4) * scs_to_blend_matrix().inverted() * (
                            offset_matrix.inverted() * location)
Example #47
0
def get_scs_transformation_components(matrix):
    """Takes an matrix and returns its transformations for SCS game engine.

    :param matrix: Matrix
    :type matrix: Matrix
    :return: Location (vector), rotation (quaternion), scale (vector)
    :rtype: tuple of Vector
    """
    export_scale = _get_scs_globals().export_scale
    loc = convert_location_to_scs(matrix.to_translation())
    mat_qua = change_to_scs_quaternion_coordinates(matrix.to_quaternion())
    qua = (mat_qua.w, mat_qua.x, mat_qua.y, mat_qua.z)
    sca = matrix.to_scale()
    sca = (sca.x * export_scale, sca.z * export_scale, sca.y * export_scale)
    return loc, qua, sca
Example #48
0
def get_mesh(obj):
    """
    Returns Mesh data of provided Object (un)affected with specified Modifiers, which are
    evaluated as within provided Scene.
    """
    scene = bpy.context.scene
    disabled_modifiers = []

    # always disable armature modifiers from SCS animations
    # to prevent vertex rest position change because of the animation
    sibling_objs = get_siblings(obj)
    for modifier in obj.modifiers:
        if modifier.type == "ARMATURE" and modifier.object in sibling_objs and modifier.object.type == "ARMATURE":
            disabled_modifiers = disable_modifier(modifier, disabled_modifiers)

    if _get_scs_globals().output_type.startswith('def'):
        if _get_scs_globals().apply_modifiers:
            if _get_scs_globals().exclude_edgesplit:
                disabled_modifiers.append(disable_modifiers(obj, modifier_type_to_disable='EDGE_SPLIT'))
            mesh = obj.to_mesh(scene, True, 'PREVIEW')
        else:
            mesh = obj.data
    else:
        if _get_scs_globals().apply_modifiers:
            mesh = obj.to_mesh(scene, True, 'PREVIEW')
        else:
            if _get_scs_globals().include_edgesplit:
                disabled_modifiers.append(disable_modifiers(obj, modifier_type_to_disable='EDGE_SPLIT', inverse=True))
                mesh = obj.to_mesh(scene, True, 'PREVIEW')
            else:
                disabled_modifiers.append(disable_modifiers(obj, modifier_type_to_disable='ANY', inverse=True))
                mesh = obj.to_mesh(scene, True, 'PREVIEW')

    restore_modifiers(obj, disabled_modifiers)

    return mesh
Example #49
0
    def execute_export(self, context, without_preview, menu_filepath=None):
        """Executes export.

        :param context: operator context
        :type context: bpy_struct
        :param without_preview: is export run without preview?
        :type without_preview: bool
        :param menu_filepath: filepath used from menu export, if not provided export is done to none menu set path
        :type menu_filepath: str
        :return: success of batch export
        :rtype: {'FINISHED'} | {'CANCELLED'}
        """

        # show all collections, if normal export, so all modifiers will be applied correctly
        if without_preview:
            self.init()

        init_obj_list = self.get_objects_for_export()

        # check extension for EF format and properly assign it to name suffix
        ef_name_suffix = ""
        if _get_scs_globals().export_output_type == "EF":
            ef_name_suffix = ".ef"

        try:
            result = _export.batch_export(self,
                                          init_obj_list,
                                          name_suffix=ef_name_suffix,
                                          menu_filepath=menu_filepath)
        except Exception as e:

            result = {"CANCELLED"}
            context.window.cursor_modal_restore()

            import traceback

            trace_str = traceback.format_exc().replace("\n", "\n\t   ")
            lprint("E Unexpected %r accured during batch export:\n\t   %s",
                   (type(e).__name__, trace_str),
                   report_errors=1,
                   report_warnings=1)

        # restore collections visiblities if normal export
        if without_preview:
            self.finish()

        return result
Example #50
0
    def get_objects_for_export(self):
        """Get objects for export, list filtered and extended depending on export scope.

        :return: list of objects to export calculated from selection
        :rtype: list[bpy.types.Object]
        """

        # if cached, just return
        if self.cached_objects:
            return self.cached_objects

        objs_to_export = []

        export_scope = _get_scs_globals().export_scope
        if export_scope == "selection":
            for root in _object_utils.gather_scs_roots(
                    bpy.context.selected_objects):
                objs_to_export.append(root)

                children = _object_utils.get_children(root)
                children_unselected = []
                children_selected = []

                for child_obj in children:
                    if child_obj.select_get():
                        children_selected.append(child_obj)
                    elif child_obj.users_scene:  # unlinked objects shouldn't be exported
                        children_unselected.append(child_obj)

                # if any children was selected make sure, to export only them
                if len(children_selected) > 0:
                    objs_to_export.extend(children_selected)
                else:
                    objs_to_export.extend(children_unselected)
        elif export_scope == "scene":
            objs_to_export = tuple(bpy.context.scene.objects)
        elif export_scope == "scenes":
            scenes_objs = set()
            for scene in bpy.data.scenes:
                scenes_objs.update(scene.objects)
            objs_to_export = tuple(scenes_objs)

        # cache filtered list, to be able to retrive it quickly on second call
        self.cached_objects = objs_to_export

        return self.cached_objects
Example #51
0
    def draw(self, context):
        layout = self.get_layout()
        scs_globals = _get_scs_globals()

        # scs tools main panel if config is being updated
        layout.enabled = not scs_globals.config_update_lock

        layout.use_property_split = True
        layout.use_property_decorate = False
        layout.enabled = scs_globals.display_locators and not scs_globals.config_update_lock

        layout.prop(scs_globals, 'locator_size')
        layout.prop(scs_globals, 'locator_empty_size')
        layout.prop(scs_globals, 'locator_prefab_wire_color')
        layout.prop(scs_globals, 'locator_model_wire_color')
        layout.prop(scs_globals, 'locator_coll_wire_color')
        layout.prop(scs_globals, 'locator_coll_face_color')
Example #52
0
    def draw(self, context):
        """UI draw function."""
        layout = self.layout
        scene = context.scene
        scs_globals = _get_scs_globals()

        if scene:

            # GLOBAL SETTINGS PANEL
            _draw_global_settings_panel(scene, layout, scs_globals)

            # EXPORT PANEL
            if context.mode == 'OBJECT':
                _draw_export_panel(scene, layout, scs_globals)

            # CONVERSION PANEL
            _draw_conversion_panel(layout, scs_globals)
Example #53
0
def hookup_id_to_hookup_name(hookup_id):
    """Takes a Hookup ID string and returns the whole Hookup Name
    or original ID string if it doesn't exists in Hookup inventory.

    :param hookup_id: Hookup ID (as saved in PIM)
    :type hookup_id: str
    :return: Hookup Name (as used in Blender UI)
    :rtype: str
    """
    hookup_name = hookup_id
    for rec in _get_scs_globals().scs_hookup_inventory:
        rec_id = rec.name.split(':', 1)[1].strip()
        if rec_id == hookup_id:
            hookup_name = rec.name
            break

    return hookup_name
Example #54
0
def update_traffic_rules_library_rel_path(scs_traffic_rules_inventory,
                                          traffic_rules_library_rel_path,
                                          readonly=False):
    """The function deletes and populates again a list of Traffic Rules names in inventory. It also updates corresponding record in config file.

    :param traffic_rules_library_rel_path: Relative path to the directory with Traffic Rules files
    :type traffic_rules_library_rel_path: str
    """
    traffic_rules_library_filepath = _path_utils.get_abs_path(
        traffic_rules_library_rel_path)
    if traffic_rules_library_filepath:

        if _get_scs_globals().traffic_rules_library_use_infixed:
            traffic_rules_library_filepaths = _path_utils.get_all_infixed_file_paths(
                traffic_rules_library_filepath)
        else:
            traffic_rules_library_filepaths = [traffic_rules_library_filepath]

        # CLEAR INVENTORY
        scs_traffic_rules_inventory.clear()

        for traffic_rules_library_filepath in traffic_rules_library_filepaths:

            trul_container = _sii.get_data_from_file(
                traffic_rules_library_filepath)
            if trul_container:

                # ADD ALL ITEMS FROM CONTAINER INTO INVENTORY
                for item in trul_container:
                    if item.type == 'traffic_rule_data':
                        if item.id.startswith('traffic_rule.'):
                            traffic_rule_item = scs_traffic_rules_inventory.add(
                            )
                            traffic_rule_item.name = item.id[13:]
                            # traffic_rule_item.item_id = item.id[13:]

                            if 'rule' in item.props:
                                traffic_rule_item.rule = item.props['rule']

                            if 'num_params' in item.props:
                                traffic_rule_item.num_params = str(
                                    item.props['num_params'])

    if not readonly:
        update_item_in_file('Paths.TrafficRulesRelFilePath',
                            traffic_rules_library_rel_path)
Example #55
0
def get_global_export_path():
    """Gets global export path.
    If default export path is empty and blend file is saved inside current scs project path  -> return blend file dir;
    Otherwise return scs project path combined with default export path.
    :return: global export path defined by directory of saved blend file and default export path from settings
    :rtype: str
    """

    scs_project_path = _get_scs_globals().scs_project_path
    is_blend_file_within_base = bpy.data.filepath != "" and startswith(bpy.data.filepath, scs_project_path)
    default_export_path = bpy.context.scene.scs_props.default_export_filepath

    # if not set try to use Blender filepath
    if default_export_path == "" and is_blend_file_within_base:
        return os.path.dirname(bpy.data.filepath)
    else:
        return os.path.join(scs_project_path, default_export_path.strip("//"))
Example #56
0
def update_tsem_library_rel_path(scs_tsem_profile_inventory,
                                 tsem_library_rel_path,
                                 readonly=False):
    """The function deletes and populates again a list of Traffic Semaphore Profile names in inventory. It also updates corresponding record in
    config file.

    :param tsem_library_rel_path: Relative path to the directory with Traffic Semaphore Profile files
    :type tsem_library_rel_path: str
    """
    tsem_library_filepath = _path_utils.get_abs_path(tsem_library_rel_path)
    if tsem_library_filepath:

        if _get_scs_globals().tsem_library_use_infixed:
            tsem_library_filepaths = _path_utils.get_all_infixed_file_paths(
                tsem_library_filepath)
        else:
            tsem_library_filepaths = [tsem_library_filepath]

        # CLEAR INVENTORY
        scs_tsem_profile_inventory.clear()

        for tsem_library_filepath in tsem_library_filepaths:

            tsem_container = _sii.get_data_from_file(tsem_library_filepath)
            if tsem_container:

                # ADD ALL ITEMS FROM CONTAINER INTO INVENTORY
                for item in tsem_container:
                    if item.type == 'tr_semaphore_profile':
                        if item.id.startswith('tr_sem_prof.'):
                            if 'name' in item.props:
                                tsem_name = item.props['name']
                            else:
                                continue

                            tsem_item = scs_tsem_profile_inventory.add()
                            tsem_item.name = tsem_name + " : " + item.id[12:]
                            tsem_item.item_id = item.id[12:]

                            if 'model' in item.props:
                                tsem_item.model = item.props['model'][0]

    if not readonly:
        update_item_in_file('Paths.TSemProfileRelFilePath',
                            tsem_library_rel_path)
Example #57
0
    def draw(self, context):
        """
        :param context:
        :return:
        """

        scs_globals = _get_scs_globals()

        # importer_version = round(import_pix.version(), 2)
        layout = self.layout
        box1 = layout.box()

        row = box1.row()
        row.prop(scs_globals, "import_scale")

        box2 = layout.box()

        row = box2.row()
        row.prop(scs_globals, "import_pim_file", toggle=True)
        if scs_globals.import_pim_file:
            row = box2.row()
            row.prop(scs_globals, "auto_welding")
        row = box2.row()
        row.prop(scs_globals, "import_pit_file", toggle=True)
        if scs_globals.import_pit_file:
            row = box2.row()
            row.prop(scs_globals, "load_textures")
        row = box2.row()
        row.prop(scs_globals, "import_pic_file", toggle=True)
        row = box2.row()
        row.prop(scs_globals, "import_pip_file", toggle=True)
        row = box2.row()
        row.prop(scs_globals, "import_pis_file", toggle=True)
        if scs_globals.import_pis_file:
            # row = box2.row()
            # row.prop(_get_scs_globals(), "connected_bones")
            row = box2.row()
            row.prop(scs_globals, "bone_import_scale")
            row = box2.row()
            row.prop(scs_globals, "import_pia_file", toggle=True)
            if scs_globals.import_pia_file:
                row = box2.row()
                row.prop(scs_globals, "include_subdirs_for_pia")

        ui.shared.draw_debug_settings(layout)
Example #58
0
    def draw(self, context):
        layout = self.get_layout()
        scs_globals = _get_scs_globals()

        layout.use_property_split = True
        layout.use_property_decorate = False

        # scs tools main panel if config is being updated
        layout.enabled = not scs_globals.config_update_lock

        layout.prop(scs_globals, 'drawing_mode', expand=True)

        layout.prop(scs_globals, 'icon_theme')
        layout.prop(scs_globals, 'display_info')
        row = _shared.create_row(layout, use_split=True, align=True, enabled=scs_globals.display_info != "none")
        row.prop(scs_globals, 'info_text_color')
        layout.prop(scs_globals, 'base_paint_color')
        layout.prop(scs_globals, 'show_preview_models')
Example #59
0
def pre_save(scene):
    # remove custom icons from blender datablock
    icon_list = _ICONS_consts.Types.as_list()
    for icon in icon_list:
        if icon in bpy.data.images:
            img = bpy.data.images[icon]
            img.use_fake_user = False
            img.user_clear()

            bpy.data.images.remove(img)

    # clear all not needed inventories
    scs_globals = _get_scs_globals()
    scs_globals.scs_hookup_inventory.clear()
    scs_globals.scs_matsubs_inventory.clear()
    scs_globals.scs_sign_model_inventory.clear()
    scs_globals.scs_traffic_rules_inventory.clear()
    scs_globals.scs_tsem_profile_inventory.clear()
Example #60
0
def get_abs_path(path_in, subdir_path='', is_dir=False, skip_mod_check=False):
    """Gets absolute path to the "SCS Project Base Path" if given path is relative (starts with: "//"),
    otherwise original path is returned.
    If relative path is existing and valid, it returns the absolute path, otherwise None.
    Optionally a subdir_path can be provided, which will be added to the 'SCS Project Base Path'.
    If skipping of mod check is not specified then function will also try to look in two
    parent base directories, in the case "SCS Project Base Path" is currently set to mod/dlc package.

    :param path_in: Absolute or relative path to current 'SCS Project Base path'
    :type path_in: str
    :param subdir_path: Additional subdirs can be provided, they will be added to the 'SCS Project Base Path'
    :type subdir_path: str
    :param is_dir: flag specifying if given path should be directory
    :type is_dir: bool
    :param skip_mod_check: flag specifying if check for dlc/mod should be skipped
    :type skip_mod_check: bool
    :return: Absolute path or None
    :rtype: str
    """
    root_path = _get_scs_globals().scs_project_path
    if subdir_path != '':
        root_path = os.path.join(root_path, subdir_path)

    if path_in.startswith("//"):
        if len(root_path) > 2:
            result = os.path.join(root_path, path_in[2:])
        else:
            result = None
    else:
        result = path_in

    existance_check = os.path.isdir if is_dir else os.path.isfile

    if result is not None and not existance_check(result) and not skip_mod_check:
        result = get_abs_path(path_in, subdir_path="../base", is_dir=is_dir, skip_mod_check=True)

    if result is not None and not existance_check(result) and not skip_mod_check:
        result = get_abs_path(path_in, subdir_path="../../base", is_dir=is_dir, skip_mod_check=True)

    # finally if file/dir not found return correct abs path, not the one from parent dirs
    if result is not None and not existance_check(result) and not skip_mod_check:
        result = get_abs_path(path_in, subdir_path=subdir_path, is_dir=is_dir, skip_mod_check=True)

    return result