0

i'm trying to create a Geometry Nodes->group input->new socket and it just shows:

  File "C:\Users\a111\Documents\untitled.blend\Text", line 21, in <module>
  File "C:\Users\a111\Downloads\blender-3.1.2-candidate+v31.2cfca7d9101d-windows.amd64-release\blender-3.1.2-candidate+v31.2cfca7d9101d-windows.amd64-release\3.1\scripts\modules\bpy\ops.py", line 132, in __call__
    ret = _op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.node.tree_socket_add.poll() failed, context is incorrect
Error: Python script failed, check the message in the system console

Here is my main file:


import bpy
from imports import create_collection, move_all_to_coll, create_object, create_objects_from_list

create 2 collections named "DISTRIBUTOR" and "CONTENTS"

create_collection("DISTRIBUTOR") create_collection("CONTENTS")

create objects in "SCENE Collection" - cube, sphere, cone, cylinder

create_objects_from_list('cube', 'sphere', 'cone', 'cylinder')

move objects from main collection to "CONTENTS Collection"

move_all_to_coll("CONTENTS")

create object in "DISTRIBUTOR Collection" - cube

create_object('cube')

move cube to "DISTRIBUTOR Collection"

move_all_to_coll("DISTRIBUTOR")

add geometry node to the cube with custom Group Inputs fields

bpy.context.active_object.modifiers.new("Group Input", 'NODES') #bpy.data.node_groups['Geometry Nodes'].nodes["Group Input"] bpy.ops.node.tree_socket_add(in_out='IN') bpy.data.node_groups["Geometry Nodes.001"].active_input = 1 bpy.data.node_groups["Geometry Nodes.001"].inputs[1].name = "Contents" bpy.ops.node.tree_socket_change_type(in_out='IN', socket_type='NodeSocketCollection') bpy.ops.node.tree_socket_add(in_out='IN') bpy.data.node_groups["Geometry Nodes.001"].active_input = 2 bpy.data.node_groups["Geometry Nodes.001"].inputs[2].name = "Min in group" bpy.ops.node.tree_socket_change_type(in_out='IN', socket_type='NodeSocketInt') bpy.data.node_groups["Geometry Nodes.001"].inputs[2].min_value = 1 bpy.data.node_groups["Geometry Nodes.001"].inputs[2].max_value = 3 bpy.ops.node.tree_socket_add(in_out='IN') bpy.data.node_groups["Geometry Nodes.001"].active_input = 3 bpy.data.node_groups["Geometry Nodes.001"].inputs[3].name = "Max in group" bpy.data.node_groups["Geometry Nodes.001"].inputs[3].default_value = 4 bpy.data.node_groups["Geometry Nodes.001"].inputs[3].min_value = 4 bpy.data.node_groups["Geometry Nodes.001"].inputs[3].max_value = 6

These are my imports:

# function that creates objects, obj can be a tuple of objects
def create_objects_from_list(*objs):
    for obj in objs:
        create_object(obj)

def create_object(obj): # dict of avalaible objects objects = { "cube": bpy.ops.mesh.primitive_cube_add, "cone": bpy.ops.mesh.primitive_cone_add, "cylinder": bpy.ops.mesh.primitive_cylinder_add, "sphere": bpy.ops.mesh.primitive_uv_sphere_add, } # loop through the dict for key, value in objects.items(): # if key is equal to the obj argument if key.lower() == obj.lower(): # call the value function value() # break the loop break return bpy.context.object

def create_collection(name): """ Create a new collection. """ collection = bpy.data.collections.new(name) bpy.context.scene.collection.children.link(collection)

def move_all_to_coll(coll_name): # Set target collection move_to = bpy.data.collections[coll_name] # Set source collection objects move_from = bpy.data.scenes['Scene'].collection.objects to_unlink = [] # If target found and object list not empty if move_from: # Loop through all objects for ob in move_from: try: move_to.objects.link(ob) except RuntimeError: pass to_unlink.append(ob) # Loop through to_unlink list for ob in to_unlink: move_from.unlink(ob) to_unlink.clear() ```

Gorgious
  • 30,723
  • 2
  • 44
  • 101
Maksym
  • 1

1 Answers1

0

You need to pass a context to methods called from the bpy.ops.node module.

ctx_override = bpy.context.copy()

for area in bpy.context.screen.areas: if area.type == "NODE_EDITOR": ctx_override['area'] = area break;

bpy.ops.node.tree_socket_add(ctx_override, in_out='IN')

Harry McKenzie
  • 10,995
  • 8
  • 23
  • 51