1
$\begingroup$

I have been struglin with this and I can’t find a way to do it. :(

I have made a script that takes care of resetting the values of some of material properties in the whole scene, but now I would like to let the user to decide what is the new default value for all those properties. Since some materials could have their own texture map attached I can not delete all the materials a assing a new one with new values.

Specifically I would want to let the user change the values for the node input [4], [5] and [7]

Could anyone shed some light on this:

import bpy


class ResetAllMaterialsOperator(bpy.types.Operator):
  """Affects all Materials in the scene"""
  bl_idname = "material.reset_all_materials_operator"
  bl_label = "Reset all Materials"
  bl_options = {'REGISTER', 'UNDO'}

  def execute(self, context):
    for mat in bpy.data.materials:
        if mat.use_nodes:
            for n in mat.node_tree.nodes:
                if n.type == "BSDF_PRINCIPLED" and n.label == "":
                        n.inputs[4].default_value = 0.75
                        n.inputs[5].default_value = 0.1
                        n.inputs[7].default_value = 0.5
                        
                        
                        
                        for l in mat.node_tree.links:
                            if l.from_node.type == "TEX_IMAGE" and l.to_node.type == "BSDF_PRINCIPLED":
                                if l.to_socket.identifier == "Alpha":
                                    mat.node_tree.links.remove(l)
                        break
                    
                                    
    return {'FINISHED'}



class testPanel(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "TEST 2"
    bl_label = "Test label"

    def draw(self, context):
        layout = self.layout

        box = layout.box()
        row = box.column()
        row.operator("material.reset_all_materials_operator")


def register():
    bpy.utils.register_class(testPanel)
    bpy.utils.register_class(ResetAllMaterialsOperator)
    


def unregister():
    bpy.utils.unregister_class(testPanel)
    bpy.utils.unregister_class(ResetAllMaterialsOperator)
    
    
    
    
if __name__ == "__main__":
    register()

Thanks in advance, Juan

$\endgroup$

1 Answer 1

2
$\begingroup$

Annotate your operator.

Add properties to the operator containing the defaults to set, which can in themselves be set.

Have added the only the metallic property, and a draw method,

enter image description here

add more to suit.

import bpy
from bpy.props import FloatProperty

class ResetAllMaterialsOperator(bpy.types.Operator):
    """Affects all Materials in the scene"""
    bl_idname = "material.reset_all_materials_operator"
    bl_label = "Reset all Materials"
    bl_options = {'REGISTER', 'UNDO'}

    metallic = FloatProperty(
            name="Metallic",
            default=0.75,
            )
    
    def draw(self, context):
        self.layout.prop(self, "metallic")
           
    def execute(self, context):
        for mat in bpy.data.materials:
            if mat.use_nodes:
                for n in mat.node_tree.nodes:
                    if n.type == "BSDF_PRINCIPLED" and n.label == "":


                        n.inputs[4].default_value = self.metallic
                        n.inputs[5].default_value = 0.1
                        n.inputs[7].default_value = 0.5

                        for l in mat.node_tree.links:
                            if l.from_node.type == "TEX_IMAGE" and l.to_node.type == "BSDF_PRINCIPLED":
                                if l.to_socket.identifier == "Alpha":
                                    mat.node_tree.links.remove(l)
                        break

        return {'FINISHED'}


class TestPanel(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_idname = "TEST_PT_test"
    bl_category = "TEST 2"
    bl_label = "Test label"

    def draw(self, context):
        layout = self.layout

        box = layout.box()
        row = box.column()
        row.operator("material.reset_all_materials_operator")

classes = (TestPanel,  ResetAllMaterialsOperator)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)


def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)


if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ Fantastic, thank you so much :) $\endgroup$ Apr 6, 2021 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.