BrendanParmer / NodeToPython

Convert Blender node groups to a Python add-on
MIT License
247 stars 23 forks source link

Having trouble cleaning up when Node Input points at an object #115

Closed sharun-s closed 3 months ago

sharun-s commented 3 months ago

I have a geom node tree (converted to a function - createTree() - via NodeToPython). It just draws a curve between a source and target object. Both objects are meshes. The Geometry node modifier is added to the source object, and the target object is passed via a Group Input. Works great during the first run.

On the second run of my addon, even though I delete all the objects (meshes and the nodegroup) before recreating things, the object passed to the Group Input is still some how alive probably because its still being referenced somewhere. It doesn't show up in the outliner viewlayer, but I do see it when changing to outliner-blend file view. It shows up greyed out. So now I get 2 objects. The TargetObject and Targetobject.001. Code looks like this -

join_obj=createTree()
mod = sourceobj.modifiers.new(name = "Join Objs", type = 'NODES')
mod.node_group = join_objs
mod['Input_2']=bpy.data.objects['Targetobject']   # Is this the right way to pass the Target?? 

This is the cleanup code maybe I am making a mistake here

if "Join Objs" in bpy.data.node_groups:
    bpy,data.node_groups.remove(bpy.data.node_groups['Join Objs'])
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_by_type(type='MESH')

And this is the create_tree code

def createTree():
    join_objs = bpy.data.node_groups.new(type = 'GeometryNodeTree', name = "Join Objs")

    #initialize join_objs nodes
    #node Self Object
    self_object = join_objs.nodes.new("GeometryNodeSelfObject")
    self_object.name = "Self Object"

    #node Group Output
    group_output = join_objs.nodes.new("NodeGroupOutput")
    group_output.name = "Group Output"
    group_output.is_active_output = True
    #join_objs outputs
    #output Geometry
    join_objs.outputs.new('NodeSocketGeometry', "Geometry")
    join_objs.outputs[0].attribute_domain = 'POINT'

    #node Join Geometry
    join_geometry = join_objs.nodes.new("GeometryNodeJoinGeometry")
    join_geometry.name = "Join Geometry"

    #node Bezier Segment
    bezier_segment = join_objs.nodes.new("GeometryNodeCurvePrimitiveBezierSegment")
    bezier_segment.name = "Bezier Segment"
    bezier_segment.mode = 'POSITION'
    #Resolution
    bezier_segment.inputs[0].default_value = 2
    #Start Handle
    bezier_segment.inputs[2].default_value = (0.0, 2.9802322387695312e-08, 0.0)
    #End Handle
    bezier_segment.inputs[3].default_value = (0.0, 0.0, -1.999999761581421)

    #node Object Info
    object_info = join_objs.nodes.new("GeometryNodeObjectInfo")
    object_info.name = "Object Info"
    object_info.transform_space = 'RELATIVE'
    #As Instance
    object_info.inputs[1].default_value = False

    #node Group Input
    group_input = join_objs.nodes.new("NodeGroupInput")
    group_input.name = "Group Input"
    #join_objs inputs
    #input Geometry
    join_objs.inputs.new('NodeSocketGeometry', "Geometry")
    join_objs.inputs[0].attribute_domain = 'POINT'

    #input Object
    join_objs.inputs.new('NodeSocketObject', "Object")
    join_objs.inputs[1].attribute_domain = 'POINT'

    #node Object Info.001
    object_info_001 = join_objs.nodes.new("GeometryNodeObjectInfo")
    object_info_001.name = "Object Info.001"
    object_info_001.transform_space = 'RELATIVE'
    #As Instance
    object_info_001.inputs[1].default_value = False

    #Set locations
    self_object.location = (-129.90524291992188, 123.85003662109375)
    group_output.location = (519.5665893554688, 225.98414611816406)
    join_geometry.location = (300.0, 242.9032440185547)
    bezier_segment.location = (307.9892578125, 132.49639892578125)
    object_info.location = (80.22540283203125, 143.56161499023438)
    group_input.location = (-256.0631103515625, 42.71624755859375)
    object_info_001.location = (64.55023193359375, -67.69190979003906)

    #Set dimensions
    self_object.width, self_object.height = 140.0, 100.0
    group_output.width, group_output.height = 140.0, 100.0
    join_geometry.width, join_geometry.height = 140.0, 100.0
    bezier_segment.width, bezier_segment.height = 140.0, 100.0
    object_info.width, object_info.height = 140.0, 100.0
    group_input.width, group_input.height = 140.0, 100.0
    object_info_001.width, object_info_001.height = 140.0, 100.0

    #initialize join_objs links
    #join_geometry.Geometry -> group_output.Geometry
    join_objs.links.new(join_geometry.outputs[0], group_output.inputs[0])
    #self_object.Self Object -> object_info.Object
    join_objs.links.new(self_object.outputs[0], object_info.inputs[0])
    #group_input.Geometry -> join_geometry.Geometry
    join_objs.links.new(group_input.outputs[0], join_geometry.inputs[0])
    #object_info.Location -> bezier_segment.Start
    join_objs.links.new(object_info.outputs[0], bezier_segment.inputs[1])
    #object_info_001.Location -> bezier_segment.End
    join_objs.links.new(object_info_001.outputs[0], bezier_segment.inputs[4])
    #group_input.Object -> object_info_001.Object
    join_objs.links.new(group_input.outputs[1], object_info_001.inputs[0])
    #bezier_segment.Curve -> join_geometry.Geometry
    join_objs.links.new(bezier_segment.outputs[0], join_geometry.inputs[0])
    return join_objs

Any idea whats happening? Thank!

(Not too familiar with blender terms and cleanup process between 2 runs of an addon so apologies if I am missing something basic)

sharun-s commented 3 months ago

Cleanup needed input node pointing at target object to be reset to None, for the target object to be removed properly. So adding this to cleanup seems to work mod['Input_2']=None