2
$\begingroup$

I have the following code snippet which I am trying to run two operators from an addon:

import bpy

# create needed operators
ng = bpy.data.node_groups['rad_sim']
image_node = ng.nodes.new(type="No_Li_Im")
falsecolor_node = ng.nodes.new(type="No_Li_Fc")

# image_node has a parameter run which returns 0 while not active and 1 while active
print("Image_node status: {}".format(image_node.run) # this gives me 0 as expected
override = {'node':image_node}
bpy.ops.node.radimage(override, 'INVOKE_DEFAULT')
print("Image_node status2: {}".format(image_node.run)) # this gives me 1 as expected

while True:
    if image_node.run:
        print("Image_node status: {}".format(image_node.run)) # this gives me 1 as expected
        continue
    else:
        break

override = {'node':falsecolor_node}
bpy.ops.node.livifc(override, 'INVOKE_DEFAULT')

image_node is a modal operator and has a parameter run which returns 0 while not active and 1 while active. Now in order to have the falsecolor_node operator successfully running I need to have image_node operator finished first. Thus, I've tried to introduce a while loop which test each time whether the the image_node operator is finished or not. However, what happens is that the execution of the image_node operator hangs while I am in the while loop. My guess is that I am running into Python's interpreter lock or something, my question is how I could bypass this somehow if possible. I was thinking to make my code above as a modal operator but I am not quite sure how to do that (not that much experience with creating my own custom operators). Thus, any help would be appreciated.

Thanks.

$\endgroup$

1 Answer 1

2
$\begingroup$

The solution that I've come up with is the following:

class ImageNodeOperator(bpy.types.Operator):
bl_idname = "myop.image_node_operator"
bl_label = "Generate Radiance Image Operator"

    def __init__(self):
        print("Start")
        self.ng = bpy.data.node_groups['rad_sim']

    def __del__(self):
        print("End")
        bpy.ops.wm.quit_blender()

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

    def modal(self, context, event):
        self.execute(context)
    
        if not self.ng.nodes['LiVi Image'].run:
        
            override = {'node':self.ng.nodes['LiVi False Colour']}
            bpy.ops.node.livifc(override, 'INVOKE_DEFAULT')
        
            return {'FINISHED'}
    
        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
    
        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

def register():
    bpy.utils.register_class(ImageNodeOperator)

def unregister():
    bpy.utils.unregister_class(ImageNodeOperator)

ng = bpy.data.node_groups['rad_sim']

print("Image_node status: {}".format(ng.nodes['LiVi Image'].run))
override = {'node':ng.nodes['LiVi Image']}
bpy.ops.node.radimage(override, 'INVOKE_DEFAULT')
print("Image_node status2: {}".format(ng.nodes['LiVi Image'].run))

register()

bpy.ops.object.image_node_operator('INVOKE_DEFAULT')

If there is a better approach please feel free to add it.

3.2 Update

Context overrides are deprecated in Blender 3.2 and are scheduled to be removed in Blender 3.3 The replacement is temp_override. The manual has examples of how to use the new function.

$\endgroup$

You must log in to answer this question.

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