1

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.

  • 1
    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?). – scurest Nov 20 '20 at 18:04
  • My objects have vertex colors so by creating a new material and the "Col" attribute I attribute the original color. – Rosanna Cap Nov 20 '20 at 18:19

2 Answers2

3

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:

Noob Cat
  • 1,222
  • 3
  • 20
  • 61
-2

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.

Duarte Farrajota Ramos
  • 59,425
  • 39
  • 130
  • 187
  • I tried adding what he wrote, but it doesn't work. What do you suggest me? Is there a way to not do it manually 645 times? – Rosanna Cap Nov 20 '20 at 18:35
  • Sounds exactly like the type of thing that is very easy to achieve with Python scripting, but it requires some knowledge of Blender's Python API, probably not something a beginner would find easily to dive into. See https://blender.stackexchange.com/questions/35653 https://blender.stackexchange.com/questions/23436 https://blender.stackexchange.com/questions/8475 – Duarte Farrajota Ramos Nov 21 '20 at 02:25