asigning a material to the active object

i’m having trouble with assigning a material to the active object, or to everything in general.

bpy.ops.material.new() makes a new material, but it isn’t assinged to any object. after searching through the API refference i couldn’t find a solution. tips?

I came with some helper functions for such tasks. You are welcome to try them out and or modify as needed.


############################################################################
# Atom's Material Library
############################################################################
def fetchIfObject (passedName= ""):
    try:
        result = bpy.data.objects[passedName]
    except:
        result = None
    return result

def returnMaterialByName(passedName):
    result = None
    for m in bpy.data.materials:
        if m.name == passedName:
            result = m
            break
    return result

def createNewMaterial (passedName):
    tempMat = bpy.data.materials.new(passedName)
    if tempMat != None:
        tempMat.diffuse_color = (0.4,0.5,0.6)
        tempMat.diffuse_shader = 'LAMBERT'
        tempMat.diffuse_intensity = 1.0
        tempMat.specular_color = (0.9,0.9,0.9)
        tempMat.specular_shader = 'COOKTORR'
        tempMat.specular_intensity = 0.5
        tempMat.alpha = 1.0
        tempMat.ambient = 0.4
        tempMat.emit = 0.1
    return tempMat

def aquireOrCreateMaterial(passedName):
    tempMat = returnMaterialByName(passedName)
    if tempMat == None:
        tempMat = createNewMaterial(passedName)
    return tempMat

def assignMaterial(passedObjectName, passedMaterialName, passedLink = "DATA"):
    result = False
    tempMaterial = aquireOrCreateMaterial(passedMaterialName)
    if tempMaterial != None:
        tempObject = fetchIfObject(passedObjectName)
        if tempObject != None:
            if tempObject.material_slots.__len__() > 0:        
                tempObject.material_slots[0].material = tempMaterial
                tempObject.material_slots[0].link = passedLink 
            else:
                obSave = bpy.context.object
                bpy.context.scene.objects.active = tempObject
                bpy.ops.object.material_slot_add()
                tempObject.material_slots[tempObject.material_slots.__len__() - 1].material = tempMaterial
                tempObject.material_slots[tempObject.material_slots.__len__() - 1].link = passedLink
                bpy.context.scene.objects.active = obSave
            result = True
        else:
            print("No object called [" + passedObjectName + "].")
    else:
        print("No material called [" + passedMaterialName + "].")     
    return result

Usage:


        myMaterial = aquireOrCreateMaterial("myMaterial")
        myMaterial.diffuse_color = (0.5,0.0,0.0)
        ob = bpy.context.active_object
        #ob = fetchIfObject("Cube") # Alternate way to get any object if you know it's name.
        assignMaterial (ob.name, "myMaterial")

aquireOrCreateMaterial will do just that. If the material of the given name already exists, it will be returned, if not a new material will be created and returned to you with the specified name.

NOTE: assignMaterial assigns the material to the DATA portion of the object by default, but you can override that by passing ‘OBJECT’ as the third optional parameter.

it works :slight_smile:
but do you realy need this amount of code to assign a simple material to the active object?
because i just pasted it in now, and don’t realy understand it…

something shorter could be like this…


import bpy
obj = bpy.context.object
mat = bpy.data.materials.new('new')
obj.data.materials.append(mat)

mat.diffuse_color = (0.6, 0.4, 0.2)
mat.specular_intensity = 0