1
$\begingroup$

So I've been trying to add Geo Nodes modifier to a created cube through custom UI panel, even though it works as intended, Blender shows me AttributeError. How can I fix this? (I'm new to coding so this might be very simple question)

import bpy

class AddGrid(bpy.types.Operator):
    bl_idname = "mesh.grid_add"
    bl_label = "Add grid"
        
    def execute(self, context):
        bpy.ops.mesh.primitive_cube_add(enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
        
        
        obj = bpy.context.active_object
        mod = obj.modifiers.new("GeometryNodes", 'NODES')
        nodeTree = bpy.data.node_groups["City"]
        mod.node_group = nodeTree
            
        return {"FINISHED"} 

class CityGenPanel(bpy.types.Panel):
    bl_label = "CityGen Generator"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'CityGen'

    def draw(self, context):
        layout = self.layout
        layout.label(text=" Generate city base panel:")

        row = layout.row()
        row.operator("mesh.grid_add", text="Create city base")
        
        gm = context.active_object.modifiers.get("GeometryNodes")
        if gm:
            row = layout.row()
            row.prop(gm, '["Socket_2"]',  text="Size X")
            row = layout.row()
            row.prop(gm, '["Socket_3"]',  text="Size Y")
            row = layout.row()
            row.prop(gm, '["Socket_4"]',  text="LB Density") 
            row = layout.row()
            row.prop(gm, '["Socket_5"]',  text="HB Density")

def register():
    bpy.utils.register_class(CityGenPanel)
    bpy.utils.register_class(AddGrid)

def unregister():
    bpy.utils.unregister_class(CityGenPanel)
    bpy.utils.unregister_class(AddGrid)

if __name__ == "__main__":
    register() 

This is the error I get

  File "D:\BlenderWorks\Diploma\city.blend\addon.py", line 31, in draw
AttributeError: 'NoneType' object has no attribute 'modifiers'
$\endgroup$

1 Answer 1

2
$\begingroup$

Because context.active_object might be a camera or light, which doesn't have modifiers.

you need to check if context.object is of type MESH.

import bpy


class AddGrid(bpy.types.Operator):
    bl_idname = "mesh.grid_add"
    bl_label = "Add grid"
        
    def execute(self, context):
        bpy.ops.mesh.primitive_cube_add(enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))

        obj = context.object
        mod = obj.modifiers.new("GeometryNodes", 'NODES')
        nodeTree = bpy.data.node_groups["City"]
        mod.node_group = nodeTree
            
        return {"FINISHED"}


class CityGenPanel(bpy.types.Panel):
    bl_label = "CityGen Generator"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'CityGen'

    def draw(self, context):
        layout = self.layout
        layout.label(text=" Generate city base panel:")

        row = layout.row()
        row.operator("mesh.grid_add", text="Create city base")
        
        if context.object and context.object.type == "MESH":
            if gm := context.object.modifiers.get("GeometryNodes"):
                row = layout.row()
                row.prop(gm, '["Socket_2"]',  text="Size X")
                row = layout.row()
                row.prop(gm, '["Socket_3"]',  text="Size Y")
                row = layout.row()
                row.prop(gm, '["Socket_4"]',  text="LB Density") 
                row = layout.row()
                row.prop(gm, '["Socket_5"]',  text="HB Density")

def register():
    bpy.utils.register_class(CityGenPanel)
    bpy.utils.register_class(AddGrid)


def unregister():
    bpy.utils.unregister_class(CityGenPanel)
    bpy.utils.unregister_class(AddGrid)


if __name__ == "__main__":
    register()
$\endgroup$

You must log in to answer this question.

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