1
$\begingroup$

I have 645 objects and I would like to repeat the same commands for each one.

I followed this tutorial: Is there a way to repeat a set of actions on an object?

But the script gives me an error.

    import bpy

bpy.ops.material.new()
bpy.ops.node.add_node(type="ShaderNodeAttribute", use_transform=True)
bpy.ops.node.translate_attach_remove_on_cancel(TRANSFORM_OT_translate={"value":(-1405.21, -1784.65, 0), "orient_type":'GLOBAL', "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)), "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, False), "mirror":True, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "cursor_transform":False, "texture_space":False, "remove_on_cancel":True, "release_confirm":False, "use_accurate":False, "use_automerge_and_split":False}, NODE_OT_attach={}, NODE_OT_insert_offset={})
bpy.data.materials["Materiale"].node_tree.nodes["Attributo"].attribute_name = "Col"
bpy.ops.node.link(detach=False)

So I run these commands for one object, then select the others and run the script, but it gives me an error.

I don't know how to use Blender or Python well but I need it for my thesis work.

Thanks to anyone who wants to help me.

$\endgroup$
2
  • 1
    $\begingroup$ You should say what you want to do for each object. I assume you want to create a new material, create a node for vertex colors, and then attach it to some socket (which one? Base Color?). $\endgroup$
    – scurest
    Nov 20 '20 at 18:04
  • $\begingroup$ My objects have vertex colors so by creating a new material and the "Col" attribute I attribute the original color. $\endgroup$ Nov 20 '20 at 18:19
1
$\begingroup$

Using bpy.ops is really not recommended, as it needs context. The context will be wrong. I suggest this instead:

If you want to create only 1 data block of a material:

import bpy

scene = bpy.context.scene

mat = bpy.data.materials.new("My Material")
mat.use_nodes = True
nodes = mat.node_tree.nodes
node_attribute = nodes.new(type="ShaderNodeAttribute")
node_attribute.location = (-1405.21, -1784.65)
node_attribute.attribute_name = "Col"

for o in scene.objects:
    if o.type =='MESH':
        o.data.materials.append(mat)

If you want to create a new material for each object instead:

import bpy

scene = bpy.context.scene

for idx ,o in enumerate(scene.objects):
    if o.type == 'MESH': 
        mat = bpy.data.materials.new("My Material_"+str(idx)) #to make your personal index into name (if you want)
        mat.use_nodes = True
        nodes = mat.node_tree.nodes
        node_attribute = nodes.new(type="ShaderNodeAttribute")
        node_attribute.location = (-1405.21, -1784.65)
        node_attribute.attribute_name = "Col"
        
        o.data.materials.append(mat)

Note: If you want work only on selected objects , you have to replace for o in scene.objects:with for o in bpy.context.selected_objects:

$\endgroup$
1
  • $\begingroup$ Thank you so much. It works! $\endgroup$ Nov 21 '20 at 15:37
-2
$\begingroup$

You can try something along the lines if

for obj in bpy.context.selected_objects:
   bpy.ops.material.new()
   ...

Although bpy.ops are operators intended for use through the UI, not direct indicated use in scripting.

$\endgroup$
2

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