1
$\begingroup$

I got a simple piece of code here which I want to change the current material of an object to a pre-made material I have named "Light"

" ob1 = bpy.data.objects.get("curtains12")

mat = bpy.data.materials.get("Light")

ob1.data.materials.append(mat) "

The code doesn't work /: For now I simply want to change the material of the object 'curtains12' (A plane with its own material already) to the material I have named "Light". Can anyone help me? Note: I intend on this happening with the click of a button, which I will implement later

Thanks for anything!

$\endgroup$
3
$\begingroup$

You can:

import bpy

#Get the object
obj = bpy.data.objects['Cube']
#Get the material
mat = bpy.data.materials['Material']

#Check all is ok
if obj and mat:

    #If a material is already assigned (material slots is not empty)
    if obj.material_slots:
        #Assign the material to the first slot
        obj.material_slots[0].material = mat
    #If no material is assigned
    else:
        #Create a new material (link/slot) for the object
        obj.data.materials.append(mat)

Explanations:

Materials are stored at two levels: object and data

'data' contains an array of materials (obj.data.materials) that allows to link the material to the object's data.

'obj' contains an array of material slots (obj.material_slots) that contains slots which give a link to the material itself (obj.material_slots[0].material) and other properties (name and link). This material is not necessarily the same as the corresponding obj.data.material (see 'link property' below).

These two lists are internally maintained coherently.

The 'link' property of the material's slot can be either 'OBJECT' or 'DATA'. That corresponds to this is the UI:

enter image description here

This distinction is useful when you 'duplicate linked' AltD an object. In this case:

  • If the link is 'OBJECT': each duplicate can have its own material in the material slot
  • If the link is 'DATA': all duplicates will share the same material

So, if we come back to the code:

#If a material is already assigned (material slots is not empty)
if obj.material_slots:
    #Assign the material to the first slot
    obj.material_slots[0].material = mat

In the first case above, using a previously created slot will assign the material coherently to the link property.

#If no material is assigned
else:
    #Create a new material (link/slot) for the object
    obj.data.materials.append(mat)

In this second case, we assign a new material which will correspond to a new slot and a default 'DATA' link mode.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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