I'm trying to create a custom UI that shows some geometry node modifier settings, So far it's working for the most part but Collection and Objects fields are grayed out :

some field are grayed out

Is there a way to make them editable as the other fields ? I've also tried a workaround by creating an EnumProperty that set collection inside the modifier , but I didn't managed to make it work as intended.

Any advices or something that would point me in the right direction would be very much apreciated ! Thanks !

Here is where I'm at with the script :

import bpy
from bpy.props import EnumProperty
from bpy.types import NodeSocketInterfaceCollection
class ModifierPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Asset Properties"
    bl_idname = "OBJECT_PT_MOD"
    bl_space_type  = "VIEW_3D"
    bl_region_type = "UI"
    bl_category    = "EnvTools"

    def poll(cls, context):
        return context.object is not None
    def draw(self, context):
        layout = self.layout
        obj    = context.object
        for mod in obj.modifiers :
            if mod.type != "NODES" : continue
            row = layout.row()
            grp = mod.node_group
            row = layout.row()
            for inp in grp.inputs :
                    if inp.type == "GEOMETRY" : continue
                    if inp.type == "COLLECTION" :
                        #row.prop(data = inp, property = "emb_col_enum", text = "")    
                        row.prop(data = mod, property = f'["{inp.identifier}"]', text = "")    
                        row = layout.row()
                    row.prop(data = mod, property = f'["{inp.identifier}"]', text = "",)
                    row = layout.row()

def col_enum_items(self, context) :
    cols = []
    t    = 0
    for c in bpy.data.collections :
        cols.append( (c.name, c.name, c.name, t) )
        #cols.append( (c.name, c.name, c.name) )
        t += 1
    return (cols)

def col_enum_get(self) :

    # work but misses default

    # locked 
    mod = socket_get_modifier(self)
    col = mod[self.identifier].name
    t = 0
    for c in bpy.data.collections :
        if c.name == col : return(t)
        t += 1

def col_enum_set(self, value) :
    #mod =  socket_get_modifier(self)
    #mod[self.identifier] = bpy.data.collections[self.emb_col_enum]
def socket_get_modifier(socket) :
    mod = None
    mod_name = socket.id_data.name
    for md in bpy.context.active_object.modifiers :
        if md.node_group.name == mod_name : mod = md

def col_enum_update(self, context) :
    mod =  socket_get_modifier(self)
    mod[self.identifier] = bpy.data.collections[self.emb_col_enum]

def register():

    NodeSocketInterfaceCollection.emb_col_enum = EnumProperty(
    update = col_enum_update)

def unregister():

if __name__ == "__main__":
  • $\begingroup$ Hello, not an answer but I think you could get a much more readable code if you used the next and/or enumerate builtin functions instead of your for loops $\endgroup$
    – Gorgious
    Commented Sep 19, 2022 at 16:44
  • $\begingroup$ try 'template_node_view()', learn more docs.blender.org/api/current/… $\endgroup$
    – Karan
    Commented Sep 19, 2022 at 18:23
  • $\begingroup$ Gorgious thanks for the tips ! @Karan thanks too ! I've looked into that and it wasn't exactly what I was looking for ! this access the node tree, not the instance of that node ( on the modifier pannel) $\endgroup$
    – Pszz
    Commented Sep 21, 2022 at 18:00

1 Answer 1


I don't know if you find an answer or not but you can make dictionary of input types and then use it with prop_search instead of prop for the non-numeric based inputs.


You must log in to answer this question.

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