From 5a38c4f5ae42b5d23878f284f739c27c0a0cf641 Mon Sep 17 00:00:00 2001 From: StandingPad Animations Date: Wed, 1 Nov 2023 08:52:25 -0500 Subject: [PATCH 1/5] Changed behavior of skin swap to be more nuanced Skin swap originally would change all image textures on all materials of the selected object, regardless of whether the user wanted to or not. This is not ideal for rigs that need multiple seperate textures. To expand the use case of skin swap, skin swap will now use a more nuanced method of swapping skins based on node name, which is an already established precedent from the MCprep Cycles Optimizer --- MCprep_addon/materials/generate.py | 13 +++++++++---- MCprep_addon/materials/skin.py | 24 ++++++++++++++++++------ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/MCprep_addon/materials/generate.py b/MCprep_addon/materials/generate.py index f17b33d9..61516c30 100644 --- a/MCprep_addon/materials/generate.py +++ b/MCprep_addon/materials/generate.py @@ -351,19 +351,19 @@ def set_texture_pack(material: Material, folder: Path, use_extra_passes: bool) - return 1 -def assert_textures_on_materials(image: Image, materials: List[Material]) -> int: +def assert_textures_on_materials(image: Image, materials: List[Material], legacy_skin_swap_behavior: bool=False) -> int: """Called for any texture changing, e.g. skin, input a list of material and an already loaded image datablock.""" # TODO: Add option to search for or ignore/remove extra maps (normal, etc) count = 0 for mat in materials: - status = set_cycles_texture(image, mat) + status = set_cycles_texture(image, mat, legacy_skin_swap_behavior) if status: count += 1 return count -def set_cycles_texture(image: Image, material: Material, extra_passes: bool=False) -> bool: +def set_cycles_texture(image: Image, material: Material, extra_passes: bool=False, legacy_skin_swap_behavior: bool=False) -> bool: """ Used by skin swap and assiging missing textures or tex swapping. Args: @@ -426,7 +426,12 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals node.mute = True node.hide = True - elif node.type == "TEX_IMAGE": + elif "MCPREP_SKIN_SWAP" in node and node.type == "TEX_IMAGE": + node.image = image + node.mute = False + node.hide = False + + elif node.type == "TEX_IMAGE" and legacy_skin_swap_behavior is True: # assume all unlabeled texture nodes should be the diffuse pass node["MCPREP_diffuse"] = True # annotate node for future reference node.image = image diff --git a/MCprep_addon/materials/skin.py b/MCprep_addon/materials/skin.py index d775d16a..b724f8ac 100644 --- a/MCprep_addon/materials/skin.py +++ b/MCprep_addon/materials/skin.py @@ -99,7 +99,7 @@ def handler_skins_load(scene): env.log("Didn't run skin reloading callback", vv_only=True) -def loadSkinFile(self, context: Context, filepath: Path, new_material: bool=False): +def loadSkinFile(self, context: Context, filepath: Path, new_material: bool=False, legacy_skin_swap_behavior: bool=False): if not os.path.isfile(filepath): self.report({'ERROR'}, f"Image file not found: {filepath}") return 1 @@ -121,7 +121,7 @@ def loadSkinFile(self, context: Context, filepath: Path, new_material: bool=Fals self.report( {'WARNING'}, "Skinswap skipped {} linked objects".format(skipped)) - status = generate.assert_textures_on_materials(image, mats) + status = generate.assert_textures_on_materials(image, mats, legacy_skin_swap_behavior) if status is False: self.report({'ERROR'}, "No image textures found to update") return 1 @@ -363,13 +363,17 @@ class MCPREP_OT_swap_skin_from_file(bpy.types.Operator, ImportHelper): name="New Material", description="Create a new material instead of overwriting existing one", default=True) + legacy_skin_swap_behavior: bpy.props.BoolProperty( + name="Use Legacy Skin Swap Behavior", + description="Swap textures in all image nodes that exist on the selected material; will be deprecated in the next release", + default=False) skipUsage: bpy.props.BoolProperty(default=False, options={'HIDDEN'}) track_function = "skin" track_param = "file import" @tracking.report_error def execute(self, context): - res = loadSkinFile(self, context, self.filepath, self.new_material) + res = loadSkinFile(self, context, self.filepath, self.new_material, self.legacy_skin_swap_behavior) if res != 0: return {'CANCELLED'} @@ -391,6 +395,10 @@ class MCPREP_OT_apply_skin(bpy.types.Operator): name="New Material", description="Create a new material instead of overwriting existing one", default=True) + legacy_skin_swap_behavior: bpy.props.BoolProperty( + name="Use Legacy Skin Swap Behavior", + description="Swap textures in all image nodes that exist on the selected material; will be deprecated in the next release", + default=False) skipUsage: bpy.props.BoolProperty( default=False, options={'HIDDEN'}) @@ -399,7 +407,7 @@ class MCPREP_OT_apply_skin(bpy.types.Operator): track_param = "ui list" @tracking.report_error def execute(self, context): - res = loadSkinFile(self, context, self.filepath, self.new_material) + res = loadSkinFile(self, context, self.filepath, self.new_material, self.legacy_skin_swap_behavior) if res != 0: return {'CANCELLED'} @@ -431,6 +439,10 @@ class MCPREP_OT_apply_username_skin(bpy.types.Operator): "If an older skin layout (pre Minecraft 1.8) is detected, convert " "to new format (with clothing layers)"), default=True) + legacy_skin_swap_behavior: bpy.props.BoolProperty( + name="Use Legacy Skin Swap Behavior", + description="Swap textures in all image nodes that exist on the selected material; will be deprecated in the next release", + default=False) skipUsage: bpy.props.BoolProperty(default=False, options={'HIDDEN'}) def invoke(self, context, event): @@ -463,7 +475,7 @@ def execute(self, context): return {'CANCELLED'} # Now load the skin - res = loadSkinFile(self, context, saveloc, self.new_material) + res = loadSkinFile(self, context, saveloc, self.new_material, self.legacy_skin_swap_behavior) if res != 0: return {'CANCELLED'} bpy.ops.mcprep.reload_skins() @@ -471,7 +483,7 @@ def execute(self, context): else: env.log("Reusing downloaded skin") ind = skins.index(user_ref) - res = loadSkinFile(self, context, paths[ind], self.new_material) + res = loadSkinFile(self, context, paths[ind], self.new_material, self.legacy_skin_swap_behavior) if res != 0: return {'CANCELLED'} return {'FINISHED'} From 5d62fbe5b20b5529f22d1577063aca031cf9046f Mon Sep 17 00:00:00 2001 From: StandingPad Animations Date: Wed, 1 Nov 2023 09:23:45 -0500 Subject: [PATCH 2/5] Fixed detection of node name in set_cycles_texture --- MCprep_addon/materials/generate.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MCprep_addon/materials/generate.py b/MCprep_addon/materials/generate.py index 61516c30..d20545a2 100644 --- a/MCprep_addon/materials/generate.py +++ b/MCprep_addon/materials/generate.py @@ -396,11 +396,11 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals # check to see nodes and their respective pre-named field, # saved as an attribute on the node - if "MCPREP_diffuse" in node: + if "MCPREP_diffuse" in node.name: node.image = image node.mute = False node.hide = False - elif "MCPREP_normal" in node and node.type == 'TEX_IMAGE': + elif "MCPREP_normal" in node.name and node.type == 'TEX_IMAGE': if "normal" in img_sets: new_img = util.loadTexture(img_sets["normal"]) node.image = new_img @@ -415,7 +415,7 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals # normal_map = node.outputs[0].links[0].to_node # principled = ... - elif "MCPREP_specular" in node and node.type == 'TEX_IMAGE': + elif "MCPREP_specular" in node.name and node.type == 'TEX_IMAGE': if "specular" in img_sets: new_img = util.loadTexture(img_sets["specular"]) node.image = new_img @@ -426,7 +426,7 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals node.mute = True node.hide = True - elif "MCPREP_SKIN_SWAP" in node and node.type == "TEX_IMAGE": + elif "MCPREP_SKIN_SWAP" in node.name and node.type == "TEX_IMAGE": node.image = image node.mute = False node.hide = False From 13ad6b2d274c63c838d07a9eb3d497eb89877e99 Mon Sep 17 00:00:00 2001 From: StandingPad Animations Date: Wed, 1 Nov 2023 10:02:44 -0500 Subject: [PATCH 3/5] Fixed error with node name checks --- MCprep_addon/materials/generate.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/MCprep_addon/materials/generate.py b/MCprep_addon/materials/generate.py index d20545a2..bd33586d 100644 --- a/MCprep_addon/materials/generate.py +++ b/MCprep_addon/materials/generate.py @@ -396,11 +396,11 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals # check to see nodes and their respective pre-named field, # saved as an attribute on the node - if "MCPREP_diffuse" in node.name: + if "MCPREP_diffuse" in node: node.image = image node.mute = False node.hide = False - elif "MCPREP_normal" in node.name and node.type == 'TEX_IMAGE': + elif "MCPREP_normal" in node and node.type == 'TEX_IMAGE': if "normal" in img_sets: new_img = util.loadTexture(img_sets["normal"]) node.image = new_img @@ -415,7 +415,7 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals # normal_map = node.outputs[0].links[0].to_node # principled = ... - elif "MCPREP_specular" in node.name and node.type == 'TEX_IMAGE': + elif "MCPREP_specular" in node and node.type == 'TEX_IMAGE': if "specular" in img_sets: new_img = util.loadTexture(img_sets["specular"]) node.image = new_img @@ -425,7 +425,11 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals else: node.mute = True node.hide = True - + + # Unlike the other names, this one + # is set with the Name option in the + # Blender UI, and thus is mapped to + # node.name and not node itself elif "MCPREP_SKIN_SWAP" in node.name and node.type == "TEX_IMAGE": node.image = image node.mute = False From 350a56c59e4e5355788c34315d4fef1006cd0515 Mon Sep 17 00:00:00 2001 From: StandingPad Animations Date: Fri, 3 Nov 2023 08:20:55 -0500 Subject: [PATCH 4/5] Changed name check to ignore duplicates --- MCprep_addon/materials/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCprep_addon/materials/generate.py b/MCprep_addon/materials/generate.py index bd33586d..9126e4b1 100644 --- a/MCprep_addon/materials/generate.py +++ b/MCprep_addon/materials/generate.py @@ -430,7 +430,7 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals # is set with the Name option in the # Blender UI, and thus is mapped to # node.name and not node itself - elif "MCPREP_SKIN_SWAP" in node.name and node.type == "TEX_IMAGE": + elif util.nameGeneralize(node.name) == "MCPREP_SKIN_SWAP" and node.type == "TEX_IMAGE": node.image = image node.mute = False node.hide = False From a3fc39d2d51898c083f90b7c89f59637957888bd Mon Sep 17 00:00:00 2001 From: "Patrick W. Crawford" Date: Mon, 1 Jan 2024 22:15:51 -0800 Subject: [PATCH 5/5] Rename and set swap_all_imgs default for texture changing function Adding positional args to fix ordered references and set, while making custom nuanced swapping still possible. --- MCprep_addon/materials/generate.py | 148 ++++++++++++++++------------- MCprep_addon/materials/skin.py | 57 +++++++---- 2 files changed, 120 insertions(+), 85 deletions(-) diff --git a/MCprep_addon/materials/generate.py b/MCprep_addon/materials/generate.py index 8bcc2b90..318fdcd2 100644 --- a/MCprep_addon/materials/generate.py +++ b/MCprep_addon/materials/generate.py @@ -335,7 +335,8 @@ def matprep_cycles(mat: Material, options: PrepOptions) -> Optional[bool]: return res -def set_texture_pack(material: Material, folder: Path, use_extra_passes: bool) -> bool: +def set_texture_pack( + material: Material, folder: Path, use_extra_passes: bool) -> bool: """Replace existing material's image with texture pack's. Run through and check for each if counterpart material exists, then @@ -347,29 +348,43 @@ def set_texture_pack(material: Material, folder: Path, use_extra_passes: bool) - return 0 image_data = util.loadTexture(image) - _ = set_cycles_texture(image_data, material, True) + _ = set_cycles_texture( + image_data, material, use_extra_passes=use_extra_passes) return 1 -def assert_textures_on_materials(image: Image, materials: List[Material], legacy_skin_swap_behavior: bool=False) -> int: - """Called for any texture changing, e.g. skin, input a list of material and - an already loaded image datablock.""" - # TODO: Add option to search for or ignore/remove extra maps (normal, etc) +def assert_textures_on_materials( + image: Image, + materials: List[Material], + extra_passes: bool = False, + swap_all_imgs: bool = True) -> int: + """Sets and returns number og modified textures across input mats. + + Called for any texture changing, e.g. skin, input a list of material and + an already loaded image datablock. + """ count = 0 for mat in materials: - status = set_cycles_texture(image, mat, legacy_skin_swap_behavior) + status = set_cycles_texture( + image, mat, extra_passes=extra_passes, swap_all_imgs=swap_all_imgs) if status: count += 1 return count -def set_cycles_texture(image: Image, material: Material, extra_passes: bool=False, legacy_skin_swap_behavior: bool=False) -> bool: - """ +def set_cycles_texture( + image: Image, + material: Material, + extra_passes: bool = False, + swap_all_imgs: bool = True) -> bool: + """Assigns + Used by skin swap and assiging missing textures or tex swapping. Args: image: already loaded image datablock material: existing material datablock extra_passes: whether to include or hard exclude non diffuse passes + swap_all_imgs: whether to force swap all images, or only do selectively """ env.log(f"Setting cycles texture for img: {image.name} mat: {material.name}") if material.node_tree is None: @@ -392,15 +407,15 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals node.hide = not is_grayscale env.log(" mix_rgb to saturate texture") - # if node.type != "TEX_IMAGE": continue - # check to see nodes and their respective pre-named field, # saved as an attribute on the node - if "MCPREP_diffuse" in node: + if node.type != 'TEX_IMAGE': + continue + elif "MCPREP_diffuse" in node: node.image = image node.mute = False node.hide = False - elif "MCPREP_normal" in node and node.type == 'TEX_IMAGE': + elif "MCPREP_normal" in node: if "normal" in img_sets: new_img = util.loadTexture(img_sets["normal"]) node.image = new_img @@ -415,7 +430,7 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals # normal_map = node.outputs[0].links[0].to_node # principled = ... - elif "MCPREP_specular" in node and node.type == 'TEX_IMAGE': + elif "MCPREP_specular" in node: if "specular" in img_sets: new_img = util.loadTexture(img_sets["specular"]) node.image = new_img @@ -425,17 +440,15 @@ def set_cycles_texture(image: Image, material: Material, extra_passes: bool=Fals else: node.mute = True node.hide = True - - # Unlike the other names, this one - # is set with the Name option in the - # Blender UI, and thus is mapped to - # node.name and not node itself - elif util.nameGeneralize(node.name) == "MCPREP_SKIN_SWAP" and node.type == "TEX_IMAGE": + + # Unlike the other names, this one is set with the Name option in the + # Blender UI, and thus is mapped to node.name and not node itself + elif util.nameGeneralize(node.name) == "MCPREP_SKIN_SWAP": node.image = image node.mute = False node.hide = False - elif node.type == "TEX_IMAGE" and legacy_skin_swap_behavior is True: + elif swap_all_imgs is True: # assume all unlabeled texture nodes should be the diffuse pass node["MCPREP_diffuse"] = True # annotate node for future reference node.image = image @@ -1127,54 +1140,57 @@ def texgen_seus(mat: Material, passes: Dict[str, Image], nodeInputs: List, use_r # nodeTexDisp["MCPREP_disp"] = True nodeTexDiff.image = image_diff + def generate_base_material( - context: Context, name: str, - path: Union[Path, str], useExtraMaps: bool + context: Context, + name: str, + path: Union[Path, str], + useExtraMaps: bool ) -> Tuple[Optional[Material], Optional[str]]: - """Generate a base material from name and active resource pack""" - try: - image = bpy.data.images.load(path, check_existing=True) - except: # if Image is not found - image = None - mat = bpy.data.materials.new(name=name) - - engine = context.scene.render.engine - if engine in ['CYCLES','BLENDER_EEVEE']: - # need to create at least one texture node first, then the rest works - mat.use_nodes = True - nodes = mat.node_tree.nodes - node_diff = create_node( - nodes, 'ShaderNodeTexImage', - name="Diffuse Texture", - label="Diffuse Texture", - location=(-380, 140), - interpolation='Closest', - image=image - ) - node_diff["MCPREP_diffuse"] = True - - # The offset and link diffuse is for default no texture setup - links = mat.node_tree.links - for n in nodes: - if n.bl_idname == 'ShaderNodeBsdfPrincipled': - links.new(node_diff.outputs[0], n.inputs[0]) - links.new(node_diff.outputs[1], n.inputs["Alpha"]) - break - - env.log("Added blank texture node") - # Initialize extra passes as well - if image: - node_spec = create_node(nodes, 'ShaderNodeTexImage') - node_spec["MCPREP_specular"] = True - node_nrm = create_node(nodes, 'ShaderNodeTexImage') - node_nrm["MCPREP_normal"] = True - # now use standard method to update textures - set_cycles_texture(image, mat, useExtraMaps) - - else: - return None, "Only Cycles and Eevee supported" + """Generate a base material from name and active resource pack""" + try: + image = bpy.data.images.load(path, check_existing=True) + except Exception: # if Image is not found + image = None + mat = bpy.data.materials.new(name=name) + + engine = context.scene.render.engine + if engine in ['CYCLES', 'BLENDER_EEVEE']: + # need to create at least one texture node first, then the rest works + mat.use_nodes = True + nodes = mat.node_tree.nodes + node_diff = create_node( + nodes, 'ShaderNodeTexImage', + name="Diffuse Texture", + label="Diffuse Texture", + location=(-380, 140), + interpolation='Closest', + image=image + ) + node_diff["MCPREP_diffuse"] = True + + # The offset and link diffuse is for default no texture setup + links = mat.node_tree.links + for n in nodes: + if n.bl_idname == 'ShaderNodeBsdfPrincipled': + links.new(node_diff.outputs[0], n.inputs[0]) + links.new(node_diff.outputs[1], n.inputs["Alpha"]) + break + + env.log("Added blank texture node") + # Initialize extra passes as well + if image: + node_spec = create_node(nodes, 'ShaderNodeTexImage') + node_spec["MCPREP_specular"] = True + node_nrm = create_node(nodes, 'ShaderNodeTexImage') + node_nrm["MCPREP_normal"] = True + # now use standard method to update textures + set_cycles_texture(image, mat, extra_passes=useExtraMaps) + + else: + return None, "Only Cycles and Eevee supported" - return mat, None + return mat, None def matgen_cycles_simple(mat: Material, options: PrepOptions) -> Optional[bool]: diff --git a/MCprep_addon/materials/skin.py b/MCprep_addon/materials/skin.py index b724f8ac..43b1c3ba 100644 --- a/MCprep_addon/materials/skin.py +++ b/MCprep_addon/materials/skin.py @@ -26,7 +26,7 @@ import bpy from bpy_extras.io_utils import ImportHelper from bpy.app.handlers import persistent -from bpy.types import Context, Image, Material +from bpy.types import Context, Material from . import generate from .. import tracking @@ -34,6 +34,13 @@ from ..conf import env + +swap_all_imgs_desc = ( + "Swap textures in all image nodes that exist on the selected \n" + "material; if off, will instead seek to only replace the images of \n" + "nodes (not image blocks) named MCPREP_SKIN_SWAP" +) + # ----------------------------------------------------------------------------- # Support functions # ----------------------------------------------------------------------------- @@ -84,7 +91,7 @@ def handler_skins_enablehack(scene): """Scene update to auto load skins on load after new file.""" try: bpy.app.handlers.scene_update_pre.remove(handler_skins_enablehack) - except: + except Exception: pass env.log("Triggering Handler_skins_load from first enable", vv_only=True) handler_skins_load(scene) @@ -95,11 +102,18 @@ def handler_skins_load(scene): try: env.log("Reloading skins", vv_only=True) reloadSkinList(bpy.context) - except: + except Exception as e: + print(e) env.log("Didn't run skin reloading callback", vv_only=True) -def loadSkinFile(self, context: Context, filepath: Path, new_material: bool=False, legacy_skin_swap_behavior: bool=False): +def loadSkinFile( + self, + context: Context, + filepath: Path, + new_material: bool = False, + swap_all_imgs: bool = False) -> int: + """Replaces image textures with target path for use in operator.""" if not os.path.isfile(filepath): self.report({'ERROR'}, f"Image file not found: {filepath}") return 1 @@ -121,7 +135,8 @@ def loadSkinFile(self, context: Context, filepath: Path, new_material: bool=Fals self.report( {'WARNING'}, "Skinswap skipped {} linked objects".format(skipped)) - status = generate.assert_textures_on_materials(image, mats, legacy_skin_swap_behavior) + status = generate.assert_textures_on_materials( + image, mats, swap_all_imgs=swap_all_imgs) if status is False: self.report({'ERROR'}, "No image textures found to update") return 1 @@ -363,17 +378,18 @@ class MCPREP_OT_swap_skin_from_file(bpy.types.Operator, ImportHelper): name="New Material", description="Create a new material instead of overwriting existing one", default=True) - legacy_skin_swap_behavior: bpy.props.BoolProperty( - name="Use Legacy Skin Swap Behavior", - description="Swap textures in all image nodes that exist on the selected material; will be deprecated in the next release", - default=False) + swap_all_imgs: bpy.props.BoolProperty( + name="Swap All Images", + description=swap_all_imgs_desc, + default=True) skipUsage: bpy.props.BoolProperty(default=False, options={'HIDDEN'}) track_function = "skin" track_param = "file import" @tracking.report_error def execute(self, context): - res = loadSkinFile(self, context, self.filepath, self.new_material, self.legacy_skin_swap_behavior) + res = loadSkinFile( + self, context, self.filepath, self.new_material, self.swap_all_imgs) if res != 0: return {'CANCELLED'} @@ -395,10 +411,10 @@ class MCPREP_OT_apply_skin(bpy.types.Operator): name="New Material", description="Create a new material instead of overwriting existing one", default=True) - legacy_skin_swap_behavior: bpy.props.BoolProperty( - name="Use Legacy Skin Swap Behavior", - description="Swap textures in all image nodes that exist on the selected material; will be deprecated in the next release", - default=False) + swap_all_imgs: bpy.props.BoolProperty( + name="Swap All Images", + description=swap_all_imgs_desc, + default=True) skipUsage: bpy.props.BoolProperty( default=False, options={'HIDDEN'}) @@ -407,7 +423,8 @@ class MCPREP_OT_apply_skin(bpy.types.Operator): track_param = "ui list" @tracking.report_error def execute(self, context): - res = loadSkinFile(self, context, self.filepath, self.new_material, self.legacy_skin_swap_behavior) + res = loadSkinFile( + self, context, self.filepath, self.new_material, self.swap_all_imgs) if res != 0: return {'CANCELLED'} @@ -439,9 +456,9 @@ class MCPREP_OT_apply_username_skin(bpy.types.Operator): "If an older skin layout (pre Minecraft 1.8) is detected, convert " "to new format (with clothing layers)"), default=True) - legacy_skin_swap_behavior: bpy.props.BoolProperty( + swap_all_imgs: bpy.props.BoolProperty( name="Use Legacy Skin Swap Behavior", - description="Swap textures in all image nodes that exist on the selected material; will be deprecated in the next release", + description=swap_all_imgs_desc, default=False) skipUsage: bpy.props.BoolProperty(default=False, options={'HIDDEN'}) @@ -475,7 +492,8 @@ def execute(self, context): return {'CANCELLED'} # Now load the skin - res = loadSkinFile(self, context, saveloc, self.new_material, self.legacy_skin_swap_behavior) + res = loadSkinFile( + self, context, saveloc, self.new_material, self.swap_all_imgs) if res != 0: return {'CANCELLED'} bpy.ops.mcprep.reload_skins() @@ -483,7 +501,8 @@ def execute(self, context): else: env.log("Reusing downloaded skin") ind = skins.index(user_ref) - res = loadSkinFile(self, context, paths[ind], self.new_material, self.legacy_skin_swap_behavior) + res = loadSkinFile( + self, context, paths[ind], self.new_material, self.swap_all_imgs) if res != 0: return {'CANCELLED'} return {'FINISHED'}