Let us just say you have a 100x100 cubes 2d grid and each cube will be assigned its own individual material. How can you do this? My code below worked initially when I created all the cubes as individual objects but it took a very very long time to create that many cubes. I was then told I can speed up this process by just copying over the mesh from the first cube to help create the next cube. This speeded up the process but when I tried to run my coloring functions all the cubes now shares the same color material. I assume this is because the new cubes inherited it's material from the creation of the first cube. I think its has something to do with the last else statement below but I am not sure.
How can I keep the speed gain from copying cube mesh to create cubes without inheriting the initial material color from the first cube as well? I asked this question in the Blender official chat a whiles ago and was told to use MaterialSlot(bpy_struct) and I have no idea how it works.
Full relevant code
class Create(Animation): def __init__(self, collection_name, H, W, y_axis): self.collection_name = collection_name self.H = H self.W = W self.master_collection = bpy.context.scene.collection self.myCol = bpy.data.collections.new(self.collection_name) # Automatically create the correct layer bpy.context.scene.collection.children.link(self.myCol) def create_block(self, x_axis, y_axis, z_axis): """ 1) Takes the Height and Width and create a 3D wall in Blender 2) Center it in the middle, assign it to the given collection 3) Translate corresponding pixel values to the correct mat color Args: H -- The height(int) W -- The width(int) collection -- The collection this block belongs too(str) """ if self.collection_name == "input_image": # try mycol flag self.x = x_axis self.y = y_axis self.z = z_axis elif self.collection_name == "filters": self.x = x_axis + 69 self.y = y_axis self.z = z_axis + 69 pixel_idx = 0 # corresponding pixel value index from the tensor bpy.ops.mesh.primitive_cube_add(size=2, view_align=False, enter_editmode=False, location=(self.x, self.y, self.z)) #create initial cube cube = bpy.context.scene.objects # remove the duplicate cube from initbpy.ops for height in range(self.H): # z-axis for width in range(self.W): # # x-axis new_cube = bpy.data.objects.new(self.collection_name + "cube", cube.data) #cube.data = mesh struct new_cube.location = (self.x, self.y, self.z) self.myCol.objects.link(new_cube) #self.master_collection.objects.unlink(new_cube) self.x += 3 if self.collection_name == "filters": self.x = x_axis + 69 elif self.collection_name == "input_image": self.x = x_axis self.z += 3 bpy.ops.object.delete() def fill_pixel_value(self, tensor_img): self.image_flatten = tensor_img self.obs = bpy.context.scene.objects for i, o in enumerate(self.obs): name = o.name #grab the cube's name mat = bpy.data.materials.get("Material") if mat is None: mat = bpy.data.materials.new( name + "_Material" ) #Change the mat color to the corresponding image_flatten tensor values # This used to work but now the first cube I made has the dominate material. mat.diffuse_color = ( self.image_flatten[i], self.image_flatten[i], self.image_flatten[i], 1 ) #RGBA # Assign it to object if o.data.materials: # assign to 1st material slot o.data.materials = mat else: # no slots o.data.materials.append(mat)