0
$\begingroup$

I'm generating lot's of cubes this was (code from the solution to one of my previous question: Low level fast way to create cube). I want to add different materials with colors to the cubes, so I've expanded the code that way, but this method seems to be slow. How can I make it faster? Full code that I'm running in a loop:

    name = "Cube"
    size = 2

    s = size / 2
    vertices = [(s, s, s),
                (s, s, -s),
                (s, -s, s),
                (s, -s, -s),
                (-s, s, s),
                (-s, s, -s),
                (-s, -s, s),
                (-s, -s, -s)]
    faces = [(0, 2, 3, 1), (0, 1, 5, 4), (2, 0, 4, 6), (1, 3, 7, 5), (3, 2, 6, 7), (4, 5, 7, 6)]

    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(vertices, [], faces)

    object = bpy.data.objects.new(name, mesh)
    object.location = pos

    mat = bpy.data.materials.new(name)
    mat.use_nodes = True
    nodes = mat.node_tree.nodes

    nodes["Principled BSDF"].inputs[0].default_value = (0.8, 0.111491, 0.169871, 1)

    bpy.data.objects[name].data.materials.append(mat)

    bpy.context.collection.objects.link(object)
$\endgroup$
7
  • $\begingroup$ may i ask why you don't use copy() for object & material? $\endgroup$
    – Chris
    Commented Nov 21, 2023 at 16:37
  • $\begingroup$ and why creating many materials? Is it just to change the color or is it for other things? $\endgroup$
    – lemon
    Commented Nov 21, 2023 at 16:40
  • $\begingroup$ @lemon I only want to set the color. The colors are going to be different for each cube. I only wrote the hard coded color for simplicity. You can imagine that they are generated randomly. $\endgroup$
    – BroDude
    Commented Nov 21, 2023 at 16:45
  • $\begingroup$ but except the color, the materials are the same? $\endgroup$
    – lemon
    Commented Nov 21, 2023 at 16:53
  • $\begingroup$ @lemon Yes, the materials only differ in color, everything else is the same. $\endgroup$
    – BroDude
    Commented Nov 21, 2023 at 16:55

1 Answer 1

1
$\begingroup$

As you only want to change the color and not the material itself, you can use an object custom property to define the color.

Object custom props can be defined here (or by code):

enter image description here

And the material can look like this, using an attribute node:

enter image description here

The code can be the following (one mat for all objects and eventually one mesh for all objects):

import bpy

mat = bpy.data.materials.new("mat")
mat.use_nodes = True

# create an attribute node, set the attribute type to object level
# and give it the name of the attribute
attribute_node = mat.node_tree.nodes.new('ShaderNodeAttribute')
attribute_node.attribute_type = 'OBJECT'
attribute_node.attribute_name = 'objColor'

# get the principled bsdf and link its base color to the attribute node
p_bsdf = mat.node_tree.nodes['Principled BSDF']
mat.node_tree.links.new(attribute_node.outputs[0], p_bsdf.inputs[0])

# create a base mesh with geometry and material
name = "Cube"
size = 1
s = size / 2
vertices = [(s, s, s),
            (s, s, -s),
            (s, -s, s),
            (s, -s, -s),
            (-s, s, s),
            (-s, s, -s),
            (-s, -s, s),
            (-s, -s, -s)]
faces = [(0, 2, 3, 1), (0, 1, 5, 4), (2, 0, 4, 6), (1, 3, 7, 5), (3, 2, 6, 7), (4, 5, 7, 6)]

mesh = bpy.data.meshes.new(name)
mesh.from_pydata(vertices, [], faces)
mesh.materials.append(mat)

# create the objects
for i in range(1, 1000):
    object = bpy.data.objects.new(name, mesh)
    # or use a copy, depending on what you need
    #object = bpy.data.objects.new(name, mesh.copy())

    # get and set some coordinates
    x, y, z = i % 10, (i / 10) % 10, (i / 100) % 10
    object.location = (x, y, z)
    # set some color to the attribute (same name as for 'attribute_node.attribute_name')
    object['objColor'] = (x / 10, y / 10, z / 10, 1)
    bpy.context.collection.objects.link(object)
$\endgroup$
2
  • $\begingroup$ Thanks for the solution! $\endgroup$
    – BroDude
    Commented Nov 22, 2023 at 9:22
  • 1
    $\begingroup$ Good job! I timed this, and it took about 0.0156 seconds which is very good considering that the version without materials took about 0.0132 seconds. $\endgroup$
    – Mr A
    Commented Nov 22, 2023 at 11:39

You must log in to answer this question.

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