예제 #1
0
    def get_scs_banner_img_data(window):
        """Loads image to blender data block, loads it to gl memory and gets bindcode address that can be used in
        bgl module for image drawing.

        :param window: window for which we should get banner image
        :type window: bpy.type.Window
        :return: (bindcode of scs banner image, width of scs banner image, height of scs banner image
        :rtype: (int, int, int)
        """

        if SCS_TOOLS_OT_Show3DViewReport.has_controls(window):
            img_name = _OP_consts.View3DReport.BT_BANNER_WITH_CTRLS_IMG_NAME
        else:
            img_name = _OP_consts.View3DReport.BT_BANNER_IMG_NAME

        if img_name not in bpy.data.images:

            img_path = os.path.join(
                _path_utils.get_addon_installation_paths()[0], "ui", "banners",
                img_name)
            img = bpy.data.images.load(img_path, check_existing=True)
            img.colorspace_settings.name = 'Raw'

        else:

            img = bpy.data.images[img_name]

        # ensure that image is loaded in GPU memory aka has proper bindcode,
        # we have to that each time because if operator is shown for long time blender might free it on it's own
        if img.bindcode == 0:
            img.gl_load()

        return img.bindcode, img.size[0], img.size[1]
예제 #2
0
def init():
    """Initialization function for getting hold of preview collection variable with already created custom icon objects.
    """

    if CUSTOM_ICONS not in _preview_collections:

        pcoll = previews.new()

        # load icons
        tools_paths = _path.get_addon_installation_paths()
        if len(tools_paths) > 0:

            for icon_type in _ICON_consts.Types.as_list():

                # create path to current icon "ui/icons/icon_type"
                icon_path = os.path.join(
                    tools_paths[0],
                    'ui' + os.sep + 'icons' + os.sep + icon_type)
                if os.path.isfile(icon_path):
                    if icon_type not in pcoll:
                        pcoll.load(icon_type, icon_path, 'IMAGE')
                else:
                    lprint(
                        "W Icon %r is missing. Please try to install addon again!",
                        (icon_type, ))

        _preview_collections[CUSTOM_ICONS] = pcoll
예제 #3
0
def _load_image(icon_type):
    """Loads image for given icon type if path exists.
    :param icon_type: one of icons type from "io_scs_tools.consts.Icons.Types"
    :type icon_type: str
    :return: True if image is succesfully loaded; False otherwise
    :rtype: bool
    """
    tools_paths = _path.get_addon_installation_paths()
    if len(tools_paths) > 0:
        # create path to current icon "ui/icons/icon_type"
        icon_path = os.path.join(tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type)
        if os.path.isfile(icon_path):
            if not icon_type in bpy.data.images:
                bpy.data.images.load(icon_path)
            return True
        else:
            lprint("W Icon %r is missing. Please try to install addon again!", (icon_type,))
            return False
예제 #4
0
def get_config_filepath():
    """Returns a valid filepath to "config.txt" file. If the file doesn't exists it creates empty one."""
    scs_installation_dirs = _path.get_addon_installation_paths()

    # SEARCH FOR CONFIG...
    scs_config_file = ''
    for i, location in enumerate(scs_installation_dirs):
        test_path = os.path.join(location, 'config.txt')
        if os.path.isfile(test_path):
            scs_config_file = test_path
            break

    # IF NO CONFIG FILE, CREATE ONE...
    if scs_config_file == '':
        scs_config_file = new_config_file(os.path.join(scs_installation_dirs[0], 'config.txt'))
        # print('\tMaking "config.txt" file:\n\t  "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt'))

    # print('SCS Blender Tools Config File:\n  "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt'))
    return scs_config_file
예제 #5
0
def get_config_filepath():
    """Returns a valid filepath to "config.txt" file. If the file doesn't exists it creates empty one."""
    scs_installation_dirs = _path_utils.get_addon_installation_paths()

    # SEARCH FOR CONFIG...
    scs_config_file = ''
    for i, location in enumerate(scs_installation_dirs):
        test_path = os.path.join(location, 'config.txt')
        if os.path.isfile(test_path):
            scs_config_file = test_path
            break

    # IF NO CONFIG FILE, CREATE ONE...
    if scs_config_file == '':
        scs_config_file = new_config_file(os.path.join(scs_installation_dirs[0], 'config.txt'))
        # print('\tMaking "config.txt" file:\n\t  "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt'))

    # print('SCS Blender Tools Config File:\n  "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt'))
    return scs_config_file
예제 #6
0
def _load_image(icon_type):
    """Loads image for given icon type if path exists.
    :param icon_type: one of icons type from "io_scs_tools.consts.Icons.Types"
    :type icon_type: str
    :return: True if image is succesfully loaded; False otherwise
    :rtype: bool
    """
    tools_paths = _path.get_addon_installation_paths()
    if len(tools_paths) > 0:
        # create path to current icon "ui/icons/icon_type"
        icon_path = os.path.join(tools_paths[0],
                                 'ui' + os.sep + 'icons' + os.sep + icon_type)
        if os.path.isfile(icon_path):
            if not icon_type in bpy.data.images:
                bpy.data.images.load(icon_path)
            return True
        else:
            lprint("W Icon %r is missing. Please try to install addon again!",
                   (icon_type, ))
            return False
예제 #7
0
def init():
    """Initialization function for getting hold of preview collection variable with already created custom icon objects.
    """

    # create new preview only once.
    # NOTE: We removed previews cleanup from code
    # because it was crashing Blender when rapidly enabling/disabling BT addon.
    # So instead of always creating new preview collection we rather reuse existing and
    # only load icons again with force reload flag, to ensure icons are always reloaded when init is called.
    if CUSTOM_ICONS not in _preview_collections:

        pcoll = previews.new()
        _preview_collections[CUSTOM_ICONS] = pcoll

    else:

        pcoll = _preview_collections[CUSTOM_ICONS]
        print(
            "INFO\t - Icon collection is already in python memory, re-using it!"
        )

    # load icons
    tools_paths = _path.get_addon_installation_paths()
    if len(tools_paths) > 0:

        for icon_type in _ICON_consts.Types.as_list():

            # create path to current icon "ui/icons/icon_type"
            icon_path = os.path.join(
                tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type)
            if os.path.isfile(icon_path):
                if icon_type not in pcoll:
                    pcoll.load(icon_type,
                               icon_path,
                               'IMAGE',
                               force_reload=True)
            else:
                lprint(
                    "W Icon %r is missing. Please try to install addon again!",
                    (icon_type, ))
예제 #8
0
def init():
    """Initialization function for getting hold of preview collection variable with already created custom icon objects.
    """

    if CUSTOM_ICONS not in _preview_collections:

        pcoll = previews.new()

        # load icons
        tools_paths = _path.get_addon_installation_paths()
        if len(tools_paths) > 0:

            for icon_type in _ICON_consts.Types.as_list():

                # create path to current icon "ui/icons/icon_type"
                icon_path = os.path.join(tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type)
                if os.path.isfile(icon_path):
                    if icon_type not in pcoll:
                        pcoll.load(icon_type, icon_path, 'IMAGE')
                else:
                    lprint("W Icon %r is missing. Please try to install addon again!", (icon_type,))

        _preview_collections[CUSTOM_ICONS] = pcoll
예제 #9
0
    def get_scs_logo_img_bindcode():
        """Loads image to blender data block, loads it to gl memory and gets bindcode address that can be used in
        bgl module for image drawing.

        :return: bindcode of scs bt logo image
        :rtype: int
        """

        if _OP_consts.View3DReport.BT_LOGO_IMG_NAME not in bpy.data.images:

            img_path = _path_utils.get_addon_installation_paths()[0] + "/ui/icons/" + _OP_consts.View3DReport.BT_LOGO_IMG_NAME
            img = bpy.data.images.load(img_path, check_existing=True)

        else:

            img = bpy.data.images[_OP_consts.View3DReport.BT_LOGO_IMG_NAME]

        # ensure that image is loaded in GPU memory aka has proper bindcode,
        # we have to that each time because if operator is shown for long time blender might free it on his own
        if img.bindcode[0] == 0:
            img.gl_load(0, GL_NEAREST, GL_NEAREST)

        return img.bindcode[0]
예제 #10
0
def register():
    """Initialization function for getting hold of preview collection variable with already created custom icon objects.
    """

    tools_paths = _path.get_addon_installation_paths()
    if len(tools_paths) <= 0:
        return

    # load icon themes
    icon_themes_dir = os.path.join(tools_paths[0], 'ui', 'icons')
    if not os.path.isdir(icon_themes_dir):
        return

    theme_idx = 0
    for theme_name in os.listdir(icon_themes_dir):
        icon_theme_dir = os.path.join(icon_themes_dir, theme_name)

        # ignore all none directory entries
        if not os.path.isdir(icon_theme_dir):
            continue

        # create new preview only once.
        # NOTE: We removed previews cleanup from code
        # because it was crashing Blender when rapidly enabling/disabling BT addon.
        # So instead of always creating new preview collection we rather reuse existing and
        # only load icons again with force reload flag, to ensure icons are always reloaded when init is called.
        if theme_name not in _cache[PCOLLS]:

            pcoll = previews.new()
            _cache[PCOLLS][theme_name] = pcoll
            _cache[PCOLLS_NAME_MAP][theme_idx] = theme_name
            _cache[PCOLLS_IDX_MAP][theme_name] = theme_idx
            theme_idx += 1
        else:

            pcoll = _cache[PCOLLS][theme_name]
            print(
                "INFO\t- Icon collection is already in python memory, re-using it!"
            )

        for icon_type in _ICON_consts.Types.as_list():

            # create path to current icon "ui/icons/<theme_name>/<icon_type>"
            icon_path = os.path.join(icon_theme_dir, icon_type)
            if os.path.isfile(icon_path):
                if icon_type not in pcoll:
                    pcoll.load(icon_type,
                               icon_path,
                               'IMAGE',
                               force_reload=True)
            else:
                print(
                    "WARNING\t- Icon %r is missing. Please try to install addon again!"
                    % icon_type)

    # if current theme doesn't exists, use first instead
    if _cache[CURRENT_THEME] not in _cache[PCOLLS] and len(_cache[PCOLLS]) > 0:
        set_theme(get_theme_name(0))
        print(
            "WARNING\t- Default icon theme doesn't exist, fallback to first available!"
        )
예제 #11
0
        def execute(self, context):

            # find group names created by Blender Tools with
            # dynamic importing of all modules from "internals/shaders" folder
            # and checking if module has "get_node_group" functions which indicates that
            # module creates node group
            groups_to_remove = [
                "AddEnvGroup",  # from v0.6
                "FresnelGroup",  # from v0.6
                "LampmaskMixerGroup",  # from v0.6
                "ReflectionNormalGroup",  # from v0.6
            ]
            for root, dirs, files in os.walk(
                    _path_utils.get_addon_installation_paths()[0] + os.sep +
                    "internals/shaders"):

                for file in files:

                    if not file.endswith(".py"):
                        continue

                    module = SourceFileLoader(root + os.sep + file, root +
                                              os.sep + file).load_module()
                    if "get_node_group" in dir(module):

                        ng = module.get_node_group()
                        groups_to_remove.append(ng.name)

            # 1. clear nodes on materials
            for mat in bpy.data.materials:

                if not mat.node_tree:
                    continue

                # also check none blender tools materials just to remove possible nodes usage of our groups
                if mat.scs_props.active_shader_preset_name == "<none>":

                    nodes_to_remove = []

                    # check for possible leftover usage of our node groups
                    for node in mat.node_tree.nodes:

                        # filter out nodes which are not node group and node groups without node tree
                        if node.type != "GROUP" or not node.node_tree:
                            continue

                        if node.node_tree.name in groups_to_remove:
                            nodes_to_remove.append(node.node_tree.name)

                    # remove possible leftover used node group nodes
                    for node_name in nodes_to_remove:
                        mat.node_tree.nodes.remove(
                            mat.node_tree.nodes[node_name])

                    continue

                mat.node_tree.nodes.clear()

            # 2. clear nodes on node groups
            for ng_name in groups_to_remove:

                if ng_name not in bpy.data.node_groups:
                    continue

                ng = bpy.data.node_groups[ng_name]
                ng.nodes.clear()

            # 3. remove node groups from blender data blocks
            for ng_name in groups_to_remove:

                if ng_name not in bpy.data.node_groups:
                    continue

                bpy.data.node_groups.remove(bpy.data.node_groups[ng_name],
                                            do_unlink=True)

            # 4. finally set preset to material again, which will update nodes and possible input interface changes
            scs_roots = _object_utils.gather_scs_roots(bpy.data.objects)
            for mat in bpy.data.materials:

                # ignore none blender tools materials
                if mat.scs_props.active_shader_preset_name == "<none>":
                    continue

                material_textures = {}
                if "scs_shader_attributes" in mat and "textures" in mat[
                        "scs_shader_attributes"]:
                    for texture in mat["scs_shader_attributes"][
                            "textures"].values():
                        tex_id = texture["Tag"].split(":")[1]
                        tex_value = texture["Value"]
                        material_textures[tex_id] = tex_value

                (preset_name, preset_section) = _material_utils.find_preset(
                    mat.scs_props.mat_effect_name, material_textures)

                if preset_section:
                    _material_utils.set_shader_data_to_material(
                        mat, preset_section)

                    # sync shader types on all scs roots by updating looks on them
                    # without this call we might end up with outdated looks raising errors once user will switch to them
                    for scs_root in scs_roots:
                        _looks.update_look_from_material(scs_root, mat, True)

            return {'FINISHED'}
예제 #12
0
        def execute(self, context):

            # find group names created by Blender Tools with
            # dynamic importing of all modules from "internals/shaders" folder
            # and checking if module has "get_node_group" functions which indicates that
            # module creates node group
            groups_to_remove = [
                "AddEnvGroup",  # from v0.6
                "FresnelGroup",  # from v0.6
                "LampmaskMixerGroup",  # from v0.6
                "ReflectionNormalGroup",  # from v0.6
            ]
            for root, dirs, files in os.walk(_path_utils.get_addon_installation_paths()[0] + os.sep + "internals/shaders"):

                for file in files:

                    if not file.endswith(".py"):
                        continue

                    module = SourceFileLoader(root + os.sep + file, root + os.sep + file).load_module()
                    if "get_node_group" in dir(module):

                        ng = module.get_node_group()
                        groups_to_remove.append(ng.name)

            # 1. clear nodes on materials
            for mat in bpy.data.materials:

                if not mat.node_tree:
                    continue

                if mat.scs_props.active_shader_preset_name == "<none>":

                    nodes_to_remove = []

                    # check for possible leftover usage of our node groups
                    for node in mat.node_tree.nodes:

                        # filter out nodes which are not node group and node groups without node tree
                        if node.type != "GROUP" or not node.node_tree:
                            continue

                        if node.node_tree.name in groups_to_remove:
                            nodes_to_remove.append(node.node_tree.name)

                    # remove possible leftover used node group nodes
                    for node_name in nodes_to_remove:
                        mat.node_tree.nodes.remove(mat.node_tree.nodes[node_name])

                    continue

                mat.node_tree.nodes.clear()

            # 2. clear nodes on node groups
            for ng_name in groups_to_remove:

                if ng_name not in bpy.data.node_groups:
                    continue

                ng = bpy.data.node_groups[ng_name]
                ng.nodes.clear()

            # 3. remove node groups from blender data blocks
            for ng_name in groups_to_remove:

                if ng_name not in bpy.data.node_groups:
                    continue

                bpy.data.node_groups.remove(bpy.data.node_groups[ng_name])

            # 4. finally set preset to material again, which will update nodes and possible input interface changes
            for mat in bpy.data.materials:

                if mat.scs_props.active_shader_preset_name == "<none>":
                    continue

                material_textures = {}
                if "scs_shader_attributes" in mat and "textures" in mat["scs_shader_attributes"]:
                    for texture in mat["scs_shader_attributes"]["textures"].values():
                        tex_id = texture["Tag"].split(":")[1]
                        tex_value = texture["Value"]
                        material_textures[tex_id] = tex_value

                (preset_name, preset_section) = _material_utils.find_preset(mat.scs_props.mat_effect_name, material_textures)

                if preset_section:
                    _material_utils.set_shader_data_to_material(mat, preset_section)

            return {'FINISHED'}