# assigning a new material for each Mesh using python

is it possible to assign a new Material(principled shader) to each mesh (or a selection of meshes) in my scene using python? The script should use the individual mesh name to name the material, and delete the existing material if there was a material before. How can i approach this problem?

• I opened a new Blender session and created a new principled Material called "Material.001" then I created a new principled Material called "Material.002" the following code allowed me to set the material I wanted to the cube and should give you a jumping off point. bpy.data.objects["Cube"].material_slots[0].material = bpy.data.materials["Material.002"] – rob Sep 26 '18 at 10:23

Run this with your objects selected:

import bpy

# I separated the creation of nodes to a function so it's easier
# to edit later if needed
def create_nodes(mat):
mat.use_nodes = True
nodes = mat.node_tree.nodes
for every_node in nodes: # this removes all existing nodes
nodes.remove(every_node)

# creating Principled node and moving it:
node.location = (-190,100)

# creating Output node and moving it:
output_node.location = (40,100)

# creating the link between the two nodes:

# this saves the currently active object so it can be restored later
active = bpy.context.object

# let's loop through all selected objects
for every_object in bpy.context.selected_objects:
# I only want to work with objects capable of having a material
if every_object.type in {'MESH','CURVE', 'SURFACE','META', 'FONT'}:
if every_object.name not in bpy.data.materials:
# if there is no material named after the object yet let's make one
mat = bpy.data.materials.new(every_object.name)
# and let's create the nodes for it
create_nodes(mat)
else:
# if the material already exists let's just use it
mat = bpy.data.materials.get(every_object.name)
if len(every_object.material_slots) == 0: # if there are no material slots
# let's make the current object active and create a material slot
bpy.context.scene.objects.active = every_object