With Python: How create cube, create two materials, set one material to one cube face

Using python I want to:

  1. create a cube
  2. create two materials
  3. set one material to 5 cube faces
  4. set one material to 1 cube face

In Blender 2.6 I used this code to achieve this:

import bmesh;

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

creates a new material

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

nombre_material = “material_gris”;
# set material name
bpy.data.materials.new(nombre_material);
# creates a new material an set its name
rojo = 1;
# set red tone for new material
azul = 0;
# set red tone for new material
verde = 0;
# set red tone for new material
bpy.data.materials[nombre_material].diffuse_color = (rojo,azul,verde);
# set color for the new material

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

creates a new material

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

nombre_material = “material_verde”;
# set material name
bpy.data.materials.new(nombre_material);
# creates a new material an set its name
rojo = 0;
# set red tone for new material
azul = 0;
# set red tone for new material
verde = 1;
# set red tone for new material
bpy.data.materials[nombre_material].diffuse_color = (rojo,azul,verde);
# set color for the new material

crea_cubo = bpy.ops.mesh.primitive_cube_add
#creates a cube
xpos = 0
# set x position for cube
ypos = 0
# set y position for cube
zpos = 0
# set z position for cube

crea_cubo(location=(xpos,ypos,zpos))
#creates a cube
material_a_usar = “material_gris”
# select a material
bpy.context.object.data.materials.append(bpy.data.materials[material_a_usar])
#uses the material in the cube
material_a_usar = “material_verde”
# select another material
bpy.context.object.data.materials.append(bpy.data.materials[material_a_usar])
#uses the material in the cube
bpy.ops.object.mode_set(mode = ‘EDIT’)
# change cube to edit mode i
bmesh.from_edit_mesh(bpy.context.object.data)
#creates a bmesh
bmesh.from_edit_mesh(bpy.context.object.data).select_mode = {‘FACE’}
#set selection mode (vertex or face)
bpy.ops.mesh.select_all(action=‘TOGGLE’)
# unselect all the faces
bmesh.from_edit_mesh(bpy.context.object.data).faces[5].select_set(True)
#select one face
bpy.context.object.active_material_index = 1
#select one material
bpy.ops.object.material_slot_assign()
#apply the material to the selected face
bpy.context.object.data.update()
#update the mesh
bpy.ops.object.mode_set(mode = ‘OBJECT’)
# exit edit mode

But this code does not work anymore in blender 2.7

When I run this code, line by line (coping line by line, then pressing enter) the code works.

But if I copy and paste the entire code appears an error after this line:

bmesh.from_edit_mesh(bpy.context.object.data).faces[5].select_set(True)

The error message says:

Traceback (most recent call last):
File “<blender_console>”, line 1, in <module>
IndexError: BMElemSeq[index]: outdated internal index table, run ensure_lookup_table() first

Why?

And in this context how can I run ensure_lookup_table() function?

I am really unfamiliar with the blender API but could this help you?

Ok.

I figured out:

import bmesh;

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

creates a new material

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

nombre_material = “material_gris”;
# set material name
bpy.data.materials.new(nombre_material);
# creates a new material an set its name
rojo = 1;
# set red tone for new material
azul = 0;
# set red tone for new material
verde = 0;
# set red tone for new material
bpy.data.materials[nombre_material].diffuse_color = (rojo,azul,verde);
# set color for the new material

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

creates a new material

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

nombre_material = “material_verde”;
# set material name
bpy.data.materials.new(nombre_material);
# creates a new material an set its name
rojo = 0;
# set red tone for new material
azul = 0;
# set red tone for new material
verde = 1;
# set red tone for new material
bpy.data.materials[nombre_material].diffuse_color = (rojo,azul,verde);
# set color for the new material

crea_cubo = bpy.ops.mesh.primitive_cube_add
#creates a cube
xpos = 0
# set x position for cube
ypos = 0
# set y position for cube
zpos = 0
# set z position for cube

crea_cubo(location=(xpos,ypos,zpos))
#creates a cube
material_a_usar = “material_gris”
# select a material
bpy.context.object.data.materials.append(bpy.data. materials[material_a_usar])
#uses the material in the cube
material_a_usar = “material_verde”
# select another material
bpy.context.object.data.materials.append(bpy.data. materials[material_a_usar])
#uses the material in the cube
bpy.ops.object.mode_set(mode = ‘EDIT’)
# change cube to edit mode i
bmesh.from_edit_mesh(bpy.context.object.data)
#creates a bmesh
bmesh.from_edit_mesh(bpy.context.object.data).sele ct_mode = {‘FACE’}
#set selection mode (vertex or face)
bpy.ops.mesh.select_all(action=‘TOGGLE’)
# unselect all the faces

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

the next line solves the problem

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

bmesh.from_edit_mesh(bpy.context.object.data).faces.ensure_lookup_table()
# run faces.ensure_lookup_table()

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

the previous line solves the problem

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

bmesh.from_edit_mesh(bpy.context.object.data).face s[5].select_set(True)
#select one face
bpy.context.object.active_material_index = 1
#select one material
bpy.ops.object.material_slot_assign()
#apply the material to the selected face
bpy.context.object.data.update()
#update the mesh
bpy.ops.object.mode_set(mode = ‘OBJECT’)
# exit edit mode

there are different ways to add mat to object

here is another method



def addmat1(obj):

	polys = obj.data.polygons
	x=0

	for i in polys:

		if x==0:
			bpy.ops.object.material_slot_add()
			obj.material_slots[x].material = newMat()
	
		polys[x].select = True
	
		bpy.ops.object.mode_set(mode='EDIT')
		bpy.ops.object.material_slot_assign() 
		bpy.ops.mesh.select_all(action='DESELECT') 
		bpy.ops.object.mode_set(mode='OBJECT')
		x += 1
	
		print ('mat added')
####





happy bl

And upgrade of the original code:

16 cubes created, painted and animated with python:

import random, bmesh;

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# crea 16 colores
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


for index in range(1, 17):
        # crea 7 materiales con textura
    nombre_material = "material_" + str(index);
        # define el nombre del material
    bpy.data.materials.new(nombre_material);
        # crea un material y lo bautiza
    rojo = random.random();
        # define el tono de rojo del material al azar
    azul = random.random();
        # define el tono de azul del material al azar
    verde = random.random();    
        # define el tono de verde del material al azar
    bpy.data.materials[nombre_material].diffuse_color = (rojo,azul,verde);
        # define el "diffuse color" (color) del material
    bpy.data.materials[nombre_material].use_shadeless = 1;
        #desactiva las sombras

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# crea el color gris
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


nombre_material = "material_gris";
    # define el nombre del material
bpy.data.materials.new(nombre_material);
    # crea un material y lo bautiza
rojo = .8;
    # define el tono de rojo del material al azar
azul = .8;
    # define el tono de azul del material al azar
verde = .8;
    # define el tono de verde del material al azar
bpy.data.materials[nombre_material].diffuse_color = (rojo,azul,verde);

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# crea 16 cubos, 
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


crea_cubo = bpy.ops.mesh.primitive_cube_add
    #crea un cubo
xpos = 0
    # define la posicion en el plano x del cubo
ypos = 0
    # define la posicion en el plano y del cubo
zpos = 0
    # define la posicion en el plano z del cubo
frame_inicial = 1
    # define el frame inicial
frame_final = 10
    # define el frame final

for index in range(1, 17):
        # crea una iteracion para crear 16 cubos
    crea_cubo(location=(xpos,ypos,zpos))
        # crea cubo en la posicion xpos,ypos,zpos
    material_a_usar = "material_gris"
        # selecciona el material a usar
    bpy.context.object.data.materials.append(bpy.data.materials[material_a_usar])
        # selecciona el cubo recien creado y le aplica el material
    material_a_usar = "material_"+ str(index)
        # selecciona el material a usar
    bpy.context.object.data.materials.append(bpy.data.materials[material_a_usar])
        # selecciona el cubo recien creado y le aplica el material
    bpy.ops.object.mode_set(mode = 'EDIT')
        # entra al modo de edicion
    bmesh.from_edit_mesh(bpy.context.object.data)
        #crea un bmesh
    bmesh.from_edit_mesh(bpy.context.object.data).select_mode = {'FACE'}
        #elige el modo de seleccion
    bpy.ops.mesh.select_all(action='TOGGLE')
        # deselecciona todo EN MODO DE EDIT
    bmesh.from_edit_mesh(bpy.context.object.data).faces.ensure_lookup_table()
        # ejecuta faces.ensure_lookup_table()
    bmesh.from_edit_mesh(bpy.context.object.data).faces[5].select_set(True) 
        #selecciona la cara 1
    bpy.context.object.active_material_index = 1
        #selecciona el material a emplear
    bpy.ops.object.material_slot_assign()
        #asigna el material a la cara seleccionada
    bpy.context.object.data.update()   
        #actualiza el mesh
    bpy.ops.object.mode_set(mode = 'OBJECT')
        # salir del modo de edicion
    bpy.context.object.keyframe_insert(data_path="location", frame=frame_inicial, index=2)
        # crea un keyframe para el objeto seleccionado
    bpy.context.object.location[2] = 5
        # define la nueva posicion en y para el objeto seleccionado
    bpy.context.object.keyframe_insert(data_path="location", frame=frame_final, index=2)
        # crea un keyframe para el objeto seleccionado
    bpy.context.object.rotation_euler[2] = 0
    bpy.context.object.keyframe_insert(data_path="rotation_euler", frame=frame_inicial, index=2)
    bpy.context.object.rotation_euler[2] = 3.1416
    bpy.context.object.keyframe_insert(data_path="rotation_euler", frame=frame_final, index=2)
    frame_inicial +=5
        #el siguiente cubo se animara 5 frames despues
    frame_final +=5
        #el siguiente cubo se animara 5 frames despues
    xpos += 3
        # tras crear el cubo modificamos la posicion en x para el siguiente cubo
    if index % 4 == 0:
            # si se colocaron 5 cubos se crea una nueva linea de cubos
        xpos = 0
            # se restablece la posicion en x
        ypos +=3    
            # modificamos la posicion en y para la siguiente linea