You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blender几何节点插件报错:'module'对象无'inputs'属性求解决

修复Pick Node Generator插件的AttributeError错误

错误原因

你遇到的AttributeError: 'module' object has no attribute 'inputs'是因为代码中把创建的NodeGroupInput节点命名为input,而input是Python的内置模块名称,导致后续调用input.outputs时,Python错误地将其识别为内置模块,而非你创建的节点对象,因此找不到对应属性。

修复步骤

  • 将代码中所有指代NodeGroupInput节点的input变量名替换为非内置关键字/模块名(比如group_input)
  • 同步修改所有引用该节点的代码行,确保变量名一致

修正后的完整代码

import bpy
from bpy.props import IntProperty, EnumProperty

bl_info = {
    "name": "Pick Node Generator",
    "author": "Johnny Matthews",
    "location": "Geometry Nodes Editor: Add Node Panel",
    "version": (1, 0),
    "blender": (3, 4, 1),
    "description": "Add a customizable pick node",
    "category": "Nodes"
}


def find_socket(list, type, name):
    for s in list:
        if s.type == type and s.name == name:
            return s


def main(self, context):
    space = context.space_data
    if space.node_tree == None:
        return
    group = space.node_tree


    cases = self.cases
    type_enum = self.type
    type = 'NodeSocket'+type_enum.capitalize()
    if type_enum == "RGBA":
        type = 'NodeSocketColor'
    if type_enum == "BOOLEAN":
        type = 'NodeSocketBool'
    if type_enum == "VALUE":
        type = 'NodeSocketFloat'

    tree = bpy.data.node_groups.new("test", 'GeometryNodeTree')
    tree.name = type_enum.capitalize() + ' Pick x'+str(cases)
    socket_case = tree.inputs.new('NodeSocketInt', 'Switch')
    for i in range(cases):
        socket_case = tree.inputs.new(type, 'Case '+str(i+self.start)+":")
    tree.inputs.new(type, 'Default ')

    socket_output = tree.outputs.new(type, 'Output')

    # 替换变量名,避免和内置input模块冲突
    group_input = tree.nodes.new("NodeGroupInput")
    group_input.location = (0, 0)
    output = tree.nodes.new("NodeGroupOutput")
    output.location = (700+(cases*200), 0)

    compares = []
    switches = []
    for i in range(cases):
        compares.append(tree.nodes.new("FunctionNodeCompare"))
        compares[i].data_type = 'INT'
        compares[i].hide = True
        compares[i].name = 'Equals '+str(i+self.start)
        compares[i].operation = 'EQUAL'
        compares[i].inputs[3].default_value = i+self.start
        compares[i].location = (200+((cases-i)*150), -i*250+(cases*250/2)-60)
        # 同步替换变量名
        tree.links.new(compares[i].inputs[2], group_input.outputs[0])

        switches.append(tree.nodes.new("GeometryNodeSwitch"))
        switches[i].location = (400+((cases-i)*150), -i*250+(cases*250/2))

        if type_enum == 'VALUE':
            switches[i].input_type = 'FLOAT'
        else:
            switches[i].input_type = type_enum

        switch_type = 0
        if type_enum in ('OBJECT', 'IMAGE', 'GEOMETRY', 'COLLECTION', 'TEXTURE', 'MATERIAL'):
            switch_type = 1

        tree.links.new(switches[i].inputs[switch_type], compares[i].outputs[0])

        sock = find_socket(switches[i].inputs, type_enum, "True")
        if sock != None:
            # 同步替换变量名
            tree.links.new(sock, group_input.outputs[i+1])

    for i in range(cases):
        if i == 0:
            sock = find_socket(switches[i].outputs, type_enum, "Output")
            if sock != None:
                tree.links.new(output.inputs[0], sock)
        else:
            sock_o = find_socket(switches[i].outputs, type_enum, "Output")
            sock_i = find_socket(switches[i-1].inputs, type_enum, "False")
            tree.links.new(sock_i, sock_o)

    sock_i = find_socket(switches[cases-1].inputs, type_enum, "False")
    # 同步替换变量名
    tree.links.new(sock_i, group_input.outputs[cases+1])

    group = group.nodes.new('GeometryNodeGroup')
    group.name = "Case Statement"
    group.node_tree = tree
    group.width = 150
    return {'FINISHED'}


class PickNodeOperator(bpy.types.Operator):
    """Pick Node Generator"""
    bl_idname = "node.swich_node"
    bl_label = "Pick Node Generator"
    bl_options = {'REGISTER', 'UNDO'}

    cases: bpy.props.IntProperty(min=0, default=6, max=25, name="# of Cases")
    start: bpy.props.IntProperty(default=0, name="Starting Value")
    type: bpy.props.EnumProperty(name="Type", items=[
        ('VALUE', 'Float', "", 0),
        ('INT', 'Int', "", 1),
        ('BOOLEAN', 'Bool', "", 2),
        ('VECTOR', 'Vector', "", 3),
        ('RGBA', 'Color', "", 4),
        ('STRING', 'String', "", 5),
        ('GEOMETRY', 'Geometry', "", 6),
        ('OBJECT', 'Object', "", 7),
        ('COLLECTION', 'Collection', "", 8),
        ('TEXTURE', 'Texture', "", 9),
        ('MATERIAL', 'Material', "", 10),
        ('IMAGE', 'Image', "", 11)
    ], default='GEOMETRY')

    @classmethod
    def poll(cls, context):
        space = context.space_data
        return space.type == 'NODE_EDITOR'

    def execute(self, context):
        main(self, context)
        return {'FINISHED'}


def menu_func(self, context):
    self.layout.operator(PickNodeOperator.bl_idname,
                         text=PickNodeOperator.bl_label)


def register():
    bpy.utils.register_class(PickNodeOperator)
    bpy.types.NODE_MT_add.append(menu_func)


def unregister():
    bpy.utils.unregister_class(PickNodeOperator)
    bpy.types.NODE_MT_add.remove(menu_func)


if __name__ == "__main__":
    register()

内容的提问来源于stack exchange,提问作者BonneJournee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:33:24