# Can anyone Fix this Little Error in My Script

I Just Have a Test Script Which Has Some Errors, As I Am Noob To Scripting I don’t Know How to Fix these errors

This script creates a Test Material and a Panel in Physics Panel and a Button is Created according to me when this Button is Pressed a Material Should be created but this is created when script is run I don’t wan’t that. This Script Creates a Node Group but I am Unable to Connect that Node -group to Material Output Node. My script is -

import bpy

#Context for Test Material
def T_M(context):
bpy.context.scene.use_nodes = True
tree = bpy.context.scene.node_tree

#removes unwanted nodes
for node in tree.nodes:
tree.nodes.remove(node)

mesh = bpy.context.object.data
mesh.materials.clear()
bpy.context.object.active_material.use_nodes = True
mat_name = "TestMat"
for mat in bpy.data.materials:
if "TestMat" in mat.name:
nodes = mat.node_tree.nodes
for node in nodes:
if node.type != 'OUTPUT_MATERIAL': # skip the material output node as we'll need it later
nodes.remove(node)

#Creating Node Group Test_Material

#Creating Group Input
group.inputs.new("NodeSocketColor", "Diffuse Color")
group.inputs.new("NodeSocketColor", "Glossy Color")
group.inputs.new("NodeSocketFloat", "Mix Factor")
group.inputs.new("NodeSocketFloat", "Glossyness")
input_node = group.nodes.new("NodeGroupInput")
input_node.location = (-800, 0)

# Creating Group Output Node

output_node = group.nodes.new("NodeGroupOutput")
output_node.location = (1500, 0)

#Creating Diffuse Node
Diffuse_node.location = (150, 100)

#Creating Glossy Node
Glossy_node.location = (300, 250)

Diffuse_node.outputs[0])

# Putting Node Group to the node editor
tree = bpy.context.object.active_material.node_tree
group_node.node_tree = group
group_node.location = (-40,300)
group_node.use_custom_color = True
group_node.color = (1,0.341,0.034)
group_node.width = (250)

#operation to add Test Material Node
class T_M(bpy.types.Operator):
"""Click this Button to Add Test Material."""
bl_label = " Test Material"

def execute(self, context):
T_M(context)
return {'FINISHED'}

#operation for Panel
class LayoutPanel(bpy.types.Panel):
bl_label = "Test Material Node"
bl_idname = "SCENE_PT_layout"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"

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

scene = context.scene

layout.label(text="_______________________________________________")

#Welcome text

row = layout.row()
layout.label(text=" Click on Test Material Button,")
layout.label(text=" and the required nodes will be added to the")
layout.label(text=" Node Editor in the form of Test Material")
layout.label(text=" Node Group.")
row = layout.row()
row = layout.row()
layout.label(text="_____________________________________________")

row = layout.row()
row = layout.row()
row = layout.row()

layout.label(text=" Test Material", icon= 'MATERIAL_DATA')
row = layout.row()
row = layout.row()
row = layout.row()
layout.label(text=" This Button will Add a Material")
row = layout.row()
row = layout.row()
row = layout.row()
row = layout.row()
layout.label(text="_______________________________________________")

#register and unregister
def register():
bpy.utils.register_class(T_M)
bpy.utils.register_class(LayoutPanel)

def unregister():

bpy.utils.unregister_class(T_M)
bpy.utils.unregister_class(LayoutPanel)

if __name__ == "__main__":
register()


I want that this Test_MaterialOP should Add this Material which is written above to the node editor using this -

 row = layout.row() row = layout.row() row.operator("t_m.addnodes", icon= 'IMPORT') row = layout.row()

And I got This

But when I click Test Material Button In Layout Panel A New Material Should Be Created with this But It is Not Happening It is Only Added When Script is Run,and not on clicking button

• Hello. This is more of a learning site than a "fix-it-forme" style personal help desk. Could you rephrase your question so that it shows what the script looks like and what specific errors it throws, rather than requiring users to download and run it themselves? – Duarte Farrajota Ramos Oct 2 '19 at 15:16
• That's a complicated script for a 'noob' - presumably it was pieced together from something else or provided as-is and not working...? It would be useful to have some history of where this has come from. An initial thought is that Python is very dependent of indentations (how much space there is to the left of lines of text). The first 'def T_M(context):' is at the same indent level as the following lines - indicating that the indentation is wrong and this would likely fail at that point, regardless of the rest. Please check the indentation with what you presumably have running. – Rich Sedman Oct 3 '19 at 7:40
• In this script I am having error in these lines as i am not able to all the process above(creation of material etc.) - " #operation to add Test Material Node class Test_MaterialOP(bpy.types.Operator): """Click this Button to Add Test Material.""" bl_idname = "t_m.addnodes" bl_label = " Test Material" def execute(self, context): Test_MaterialOP(context) return {'FINISHED'} " **I have fixed Indentation errors – Rakesh choudhary Oct 5 '19 at 14:16

There are multiple issues with your script:

1. The indentation is incorrect. Code that belongs into your T_M function isn't indented by four spaces, which results in the code being executed even though the functions wasn't called. Similarly the functions that should be part of the class aren't indented, e.g. the execute function for Test_MaterialOP.
2. The Test_MaterialOP calls Test_MaterialOP(context) in execute. I believe you intend to call T_M here. Creating another operator object is certainly not what you want.
3. The Material creation in T_M is incomplete, the code wouldn't create a connection to the Material Output node.
4. The layout code could be improved. Use layout.separator() to draw horizontal lines. Don't create empty rows that you aren't using.

These are the most obvious errors that I could spot.

The updated script still has issues. I've fixed the following problems in the script below:

1. The entire function body has to be indented by at least four spaces (more for loops and conditionals)
2. The operator name and the function to add the material should have different names. The operator is your button and the execute function what happens when the button is pressed. Therefore you need to call the function that creates the material in the execute function. The operator needs to be registered.
3. The node group was connected to the volume socket for the material output. It's now connected to the shader output.
4. Fixed for compliance with Blender's naming convention
5. Moved the panel to the 3D View sidebar in the "Test Material" tab (open with N)
6. Added bl_info so you can install as add-on.
7. Moved explanatory text to the add-on's description and the operator's description. The latter will appear when you hover over the button.

bl_info = {
"author": "Rakesh Choudhary",
"version": (1, 0),
"blender": (2, 80, 0),
"location": "View3D > Sidebar > Test Material Node",
"description": "Click on the 'Test Material' button to add a material to your object.",
"warning": "",
"wiki_url": "",
"category": "3D View"
}

import bpy

def execute(self, context):
self.create_material()
return {'FINISHED'}

def create_material(self):
bpy.context.scene.use_nodes = True
tree = bpy.context.scene.node_tree

# removes unwanted nodes
for node in tree.nodes:
tree.nodes.remove(node)

mesh = bpy.context.object.data
mesh.materials.clear()
bpy.context.object.active_material.use_nodes = True

for mat in bpy.data.materials:
if "TestMat" in mat.name:
nodes = mat.node_tree.nodes
for node in nodes:
if node.type != 'OUTPUT_MATERIAL':  # skip the material output node as we'll need it later
nodes.remove(node)

# Creating Node Group Test_Material

# Creating Group Input
group.inputs.new("NodeSocketColor", "Diffuse Color")
group.inputs.new("NodeSocketColor", "Glossy Color")
group.inputs.new("NodeSocketFloat", "Mix Factor")
group.inputs.new("NodeSocketFloat", "Glossyness")
input_node = group.nodes.new("NodeGroupInput")
input_node.location = (-800, 0)

# Creating Group Output Node

output_node = group.nodes.new("NodeGroupOutput")
output_node.location = (1500, 0)

# Creating Diffuse Node
diffuse_node.location = (150, 100)

# Creating Glossy Node
glossy_node.location = (300, 250)

# Putting Node Group to the node editor
tree = bpy.context.object.active_material.node_tree
group_node.node_tree = group
group_node.location = (-40, 300)
group_node.use_custom_color = True
group_node.color = (1, 0.341, 0.034)
group_node.width = 250

class TEST_MATERIAL_PT_layout_panel(bpy.types.Panel):
bl_label = "Test Material Node"
bl_category = "Test Material"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"

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

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

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

if __name__ == "__main__":
register()

• I have Fixed All The Indentation Errors and also now material creation is complete it is connected to Material output node. as in your answer i have completed point no - 1, 3, 4(Leave layout.separator for now because it is not creating any kind of error and i will improve it further) I think my problem is at point no 2 of your answer Please Explain it to me. – Rakesh choudhary Oct 6 '19 at 14:45
• @Rakeshchoudhary If you want to call the T_M function you need to write T_M(context) instead of Test_MaterialOP(context). – Robert Gützkow Oct 6 '19 at 15:08
• I have done as You Said You can see I have edited the question + also added screenshot I got this Material in Node editor when this script is run, I wan't that the Button "Test Material" Should be Useful and this Material should be created as Many times as I press this Button – Rakesh choudhary Oct 6 '19 at 15:45
• @Rakeshchoudhary you shouldn't change the name of the operator, just add the function call. I've updated my answer. – Robert Gützkow Oct 6 '19 at 16:31