# Assign a different material to objects within dupli_group instances

Say you have a cube and a sphere grouped as 'Group'. You instanciate that group and link it to the scene. Now when you click on the instance, there is no material panel.

See the two pictures below for a better understanding of what I'm trying to do.

Is it possible to access the duplicated objects in the dupli instance in order to give them new materials ?

The only thing I succeeded in doing is to assign a material to an object instance but not to objects within a group instance.

As requested, here's the code to create a dupli_group instance:

layers = [True] + 19*[False]

# Could replace this with bmesh method
object1 = bpy.context.active_object

object2 = bpy.context.active_object

group = bpy.data.groups.new('some_group_name')

group_instance = bpy.data.objects.new('some_group_name_instance1', None)
group_instance.dupli_type = 'GROUP'
group_instance.dupli_group = group



Then I would expect to have a way to target object1 and object2 within group_instance and to set new materials that won't affect other instances.

• Can you outline the exact steps taken to "instantiate that group" ? – Mutant Bob Jun 3 '15 at 19:25
• @MrZak I'm sorry, this doesn't answer my question. – nantille Jun 4 '15 at 14:45

Unfortunately, I think it is not possible to do exactly what you want to do.

One of the advantages of using an Empty with dupli_group is that you don't have the overhead of storing much in the way of differences (location, rotation, scale).

If you want to alter the group, you will probably have to instantate objects by copying the data from the group. There's actually a keyboard shortcut to Make Duplicates Real (Ctrl Shift A) that would work for interactive use. Since you were using python in your original project here is a small python script I wrote that might accomplish your mission:

import bpy

def mission1(group, scn):

parent = bpy.data.objects.new("parent", None)

for obj in group.objects:
o2 = obj.copy()
o2.parent = parent
for i in range(len(o2.material_slots)):
ms = o2.material_slots[i]
ms.material = o2.data.materials[i]

return parent
#
#

anchor = mission1(bpy.data.groups["Group"], bpy.context.scene)
anchor.location = [2,0,2]


The parent object is not strictly necessary, but it gives you the ability to manipulate the location and orientation of the group very much like the dupli_group empty you were using before.

An important drawback is that once you have instantiated these copies modifications to the group (adding, removing, relocating objects) will not be propagated.

• Thank you for clarifying this. I'm not sure I understand correctly, do you keep the mesh in memory or do you copy it entirely ? Since I have several thousand instances of my objects, I want to keep the mesh data shared across the instances. – nantille Jun 4 '15 at 15:14
• The object.copy() creates a new instance of the object datablock, but the mesh datablock is shared by the original and the copy. If the mesh were not shared, then it would not be necessary to use per-object materials. – Mutant Bob Jun 4 '15 at 15:17
• Ok that's what I thought, I used groups because of the dupli_group property but then it lead me to this lack of control. I was using parenting and grouping to simplify selection of instances in the viewport but this came at a certain cost. Thanks ! – nantille Jun 4 '15 at 20:53