Example #1
0
def __update_look__(self, context):
    """Hookup function for triggering update look from material in internal module of looks.
    It should be used on any property which should be saved in exported into looks.
    :param context: Blender context
    :type context: bpy.types.Context
    """

    if hasattr(context, "active_object") and hasattr(context.active_object, "active_material") and context.active_object.active_material:
        scs_root = _object_utils.get_scs_root(context.active_object)
        if scs_root:
            _looks.update_look_from_material(scs_root, context.active_object.active_material, "preset_change" in self)
Example #2
0
        def execute(self, context):
            lprint("I " + self.bl_label + "...")

            from io_scs_tools.internals.shader_presets import cache as _shader_presets_cache
            from io_scs_tools.utils import get_shader_presets_inventory as _get_shader_presets_inventory

            mat = context.material
            mat_scs_props = mat.scs_props
            """:type: io_scs_tools.properties.material.MaterialSCSTools"""
            preset = _get_shader_presets_inventory()[mat_scs_props.active_shader_preset_name]
            """:type: io_scs_tools.properties.world.ShaderPresetsInventoryItem"""

            # extract only flavor effect part of string
            flavor_effect_part = mat_scs_props.mat_effect_name[len(preset.effect):]

            new_flavor_state = not self.flavor_enabled
            flavors_suffix = ""
            for flavor in preset.flavors:
                flavor_variant_found = False
                for flavor_variant in flavor.variants:

                    if flavor_variant.name == self.flavor_name:
                        # add founded flavor to flavors suffix only if enabled
                        if new_flavor_state:
                            flavors_suffix += "." + flavor_variant.name

                        flavor_variant_found = True
                        break

                # if one variant of flavor is found skip all other variants
                if flavor_variant_found:
                    continue

                # make sure to add all other enabled flavors to flavors suffix
                for flavor_variant in flavor.variants:

                    is_in_middle = "." + flavor_variant.name + "." in flavor_effect_part
                    is_on_end = flavor_effect_part.endswith("." + flavor_variant.name)

                    if is_in_middle or is_on_end:
                        flavors_suffix += "." + flavor_variant.name

            # finally set new shader data to material
            section = _shader_presets_cache.get_section(preset, flavors_suffix)
            context.material.scs_props.mat_effect_name = preset.effect + flavors_suffix
            _material_utils.set_shader_data_to_material(context.material, section)

            # sync shader types on all scs roots by updating looks on them
            # to avoid different shader types on different scs roots for same material
            for scs_root in _object_utils.gather_scs_roots(bpy.data.objects):
                _looks.update_look_from_material(scs_root, mat, True)

            return {'FINISHED'}
Example #3
0
        def execute(self, context):
            lprint("I " + self.bl_label + "...")

            from io_scs_tools.internals import shader_presets as _shader_presets

            mat = context.material
            mat_scs_props = mat.scs_props
            """:type: io_scs_tools.properties.material.MaterialSCSTools"""
            preset = _shader_presets.get_preset(
                mat_scs_props.active_shader_preset_name)

            # extract only flavor effect part of string
            flavor_effect_part = mat_scs_props.mat_effect_name[len(preset.
                                                                   effect):]

            new_flavor_state = not self.flavor_enabled
            flavors_suffix = ""
            for flavor in preset.flavors:
                flavor_variant_found = False
                for flavor_variant in flavor.variants:

                    if flavor_variant.suffix == self.flavor_name:
                        # add founded flavor to flavors suffix only if enabled
                        if new_flavor_state:
                            flavors_suffix += "." + flavor_variant.suffix

                        flavor_variant_found = True
                        break

                # if one variant of flavor is found skip all other variants
                if flavor_variant_found:
                    continue

                # make sure to add all other enabled flavors to flavors suffix
                for flavor_variant in flavor.variants:

                    is_in_middle = "." + flavor_variant.suffix + "." in flavor_effect_part
                    is_on_end = flavor_effect_part.endswith(
                        "." + flavor_variant.suffix)

                    if is_in_middle or is_on_end:
                        flavors_suffix += "." + flavor_variant.suffix

            # if desired combination doesn't exists, abort switching and notify user
            if not _shader_presets.has_section(preset.name, flavors_suffix):
                message = "Enabling %r flavor aborted! Wanted shader combination: %r is not supported!" % (
                    self.flavor_name, preset.effect + flavors_suffix)
                lprint("E " + message)
                self.report({'WARNING'}, message)
                return {'FINISHED'}

            # finally set new shader data to material
            section = _shader_presets.get_section(preset.name, flavors_suffix)
            context.material.scs_props.mat_effect_name = preset.effect + flavors_suffix
            _material_utils.set_shader_data_to_material(
                context.material, section)

            # sync shader types on all scs roots by updating looks on them
            # to avoid different shader types on different scs roots for same material
            for scs_root in _object_utils.gather_scs_roots(bpy.data.objects):
                _looks.update_look_from_material(scs_root, mat, True)

            return {'FINISHED'}
Example #4
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'}