5
$\begingroup$

Consider:

Enter image description here

I'm having trouble with making each of these circles to have a random color and the problem is that the color is random, but that color applies to all of them.

import bpy
import random as r
import math as m
n=25

for i in range(1,n+1):

    material_i= bpy.data.materials.new(f'm{i}')
    material_i.diffuse_color=(r.uniform(0,1),r.uniform(0,1),r.uniform(0,1),1)
    bpy.context.object.data.materials.append(material_i)
    angle = ((i-1)*4*(m.pi))/n
    bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(0, 0, 0), "orient_type":'GLOBAL', "orient_matrix":((0, 0, 0), (0, 0, 0), (0, 0, 0)), "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, False), "mirror":False, "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":False, "release_confirm":False, "use_accurate":False, "use_automerge_and_split":False})
    bpy.context.object.rotation_euler[2] = angle
$\endgroup$
2
  • 3
    $\begingroup$ Please post code as code block. Easier to see, able to copy paste to test, wont be cutoff at edge of screen capture, etc... $\endgroup$
    – Ratt
    Commented Apr 14, 2021 at 17:38
  • $\begingroup$ @Ratt Here you are! you have to make an object , select it ,then run the script. in this case i have used a circle. $\endgroup$ Commented Apr 14, 2021 at 18:08

2 Answers 2

5
$\begingroup$

Part of the issue is that when you append the new material to the duplicated object you never change the index of the active material slot which remains at 0 from the initial object. If you inspect the material slots of each object in turn you continue to add another material but never assign it. I would think that instead of constantly adding additional materials you would rather just have 1 material per object in this case.

import bpy
import random as r
import math as m
n=25

for i in range(1,n+1):
    ob = bpy.context.object
    material_i= bpy.data.materials.new(f'm{i}')
    material_i.diffuse_color=(r.uniform(0,1),r.uniform(0,1),r.uniform(0,1),1)
    if not ob.material_slots:
        bpy.ops.object.material_slot_add()
        new_mat = material_i
        ob.material_slots[0].material = new_mat
    else:
        new_mat = material_i
        ob.material_slots[0].material = new_mat
    angle = ((i-1)*4*(m.pi))/n
    bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'})
    bpy.context.object.rotation_euler[2] = angle
$\endgroup$
1
  • $\begingroup$ thank you so much! $\endgroup$ Commented Apr 15, 2021 at 6:59
5
$\begingroup$

Matrices, object copies and Object Color.

Same Material with different key frames

Why does editing a material on one object change lots of other object's materials as well?

First going to give the context object the simplest of materials, that uses the object color.

enter image description here

All our linked copies will have the same material, and take on the value assigned to their respective object color.

Matrices.

For my circle have started with a skinny torus at global origin (the default)

To do what is akin to an edit mode transform of 2 in x direction will make a translation matrix and apply it the torus, which will have the effect of shifting the mesh 2 to the right while its origin remains at the center.

Next will make a rotation matrix that rotates $4 \pi / n$ radians about the z axis.

Each copy will have this rotation applied.

import bpy
from random import uniform
from mathutils import Matrix
from math import pi
n=25

T = Matrix.Translation((2, 0, 0))
R = Matrix.Rotation(4 * pi / n, 4, 'Z')
#M = R @ T

ob = bpy.context.object
ob.data.transform(T) # like an edit mode transform

coll = bpy.context.collection

for i in range(1, n+1):
    copy = ob.copy() # copy object
    copy.color = (uniform(0, 1), uniform(0, 1), uniform(0, 1), 1)
    copy.matrix_world @= R
    coll.objects.link(copy) # link to context collection
    ob = copy

enter image description here Test Run on my torus

$\endgroup$
1
  • $\begingroup$ your approach was a little different but thanks a lot! $\endgroup$ Commented Apr 15, 2021 at 7:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .