Page MenuHome

"Context is incorrect" error when creating rigid body from inside panel
Closed, ArchivedPublic

Description

System Information
Operating system: Windows 10 Home 1909 (64-bit)
Graphics card: NVidia GeForce GTX 1050 Ti

Blender Version
Broken: 2.90.0
Worked: Unknown

Short description of error

When calling bpy.ops.rigidbody.object_add() from inside of a Panel it gives the following error:

Error: Traceback (most recent call last):
  File "\Text", line 9, in execute
  File "C:\Program Files\Blender Foundation\Blender 2.90\2.90\scripts\modules\bpy\ops.py", line 201, in __call__
    ret = op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.rigidbody.object_add.poll() failed, context is incorrect

Unfortunately this completely breaks my custom rigging addon.

Exact steps for others to reproduce the error

Starting with a new General Blend file:

  1. Run the following code as a Text (it will automatically create an armature and panel):
import bpy
from bpy.utils import register_class

class Create(bpy.types.Operator):
    bl_label = "Test"
    bl_idname = "test.create"

    def execute(self, context):
        bpy.ops.mesh.primitive_cube_add(size=1.0, calc_uvs=False, enter_editmode=False, location=(6, 0, 0))
        bpy.ops.rigidbody.object_add()
        return {'FINISHED'}

class DATA_PT_test(bpy.types.Panel):
    bl_label = "Test"
    bl_region_type = 'WINDOW'
    bl_space_type = 'PROPERTIES'
    bl_context = 'object'

    def draw(self, context):
        self.layout.operator("test.create")

register_class(Create)
register_class(DATA_PT_test)
bpy.ops.object.armature_add(enter_editmode=False, location=(3, 0, 0))
  1. Select the default cube.
  1. In the Object Properties tab, find the Test panel and then click the Test button. It will correctly create a new cube and add rigid body to it.
  1. Select the armature, then click the Test button. It correctly creates the new cube, however when adding the rigid body it gives the context is incorrect error.

Event Timeline

Pauan (Pauan) added a comment.EditedSep 27 2020, 7:01 PM

Oh, I just now realized that it is actually not creating the rigid body correctly: it is creating it on the old object (the default cube), not the currently active object (the new cube).

That also seems like a bug, since that only happens when running the operator in a panel (it correctly creates the rigid body on the new cube when the operator is called from a menu).

I then tried to override the area and region, but it seems that bpy.ops.rigidbody.object_add completely ignores overrides. I then tried to create a wrapper Operator and override it, like this...

class CreateInternal(bpy.types.Operator):
    bl_label = "Test Internal"
    bl_idname = "test.create_internal"

    def execute(self, context):
        bpy.ops.mesh.primitive_cube_add(size=1.0, calc_uvs=False, enter_editmode=False, location=(6, 0, 0))
        bpy.ops.rigidbody.object_add()
        return {'FINISHED'}

class Create(bpy.types.Operator):
    bl_label = "Test"
    bl_idname = "test.create"

    def execute(self, context):
        area = None

        for x in context.screen.areas:
            if x.type == 'VIEW_3D':
                area = x
                break

        region = None

        for x in area.regions:
            if x.type == 'WINDOW':
                region = x
                break

        override = context.copy()
        override["area"] = area
        override["region"] = region

        bpy.ops.test.create_internal(override)
        return {'FINISHED'}

...but that causes Blender to immediately hard crash without any error message.

Richard Antalik (ISS) closed this task as Archived.Oct 6 2020, 12:50 PM
Richard Antalik (ISS) claimed this task.

I can not reproduce crash with your second example.

You provided operator with context copy, so active_object won't be updated. I had some trouble setting it manually though, but that was likely my fault.

I am definitely not python guru, so this is about best I could come up with:

class Create(bpy.types.Operator):
    bl_label = "Test"
    bl_idname = "test.create"

    def execute(self, context):
        bpy.ops.mesh.primitive_cube_add(size=1.0, calc_uvs=False, enter_editmode=False, location=(6, 0, 0))

        area = None
        for x in context.screen.areas:
            if x.type == 'VIEW_3D':
                area = x
                break

        bpy.ops.rigidbody.object_add({'area':area})
        return {'FINISHED'}

For help using Blender, please try one of the community websites: https://www.blender.org/community/

If you think you found a bug, please submit a new report and carefully follow the instructions. Be sure to provide system information, Blender version, and a .blend file with exact steps to reproduce the problem.

@Richard Antalik (ISS) The second example is not the bug, I provided it as extra information (you are correct that it no longer crashes in 2.91.0).

The first example is the actual bug. I just tested it again in 2.91.0 and the bug is still there. I have attached a .blend file which reproduces it.

Select Cube and click the "Test" button in the "Test View3D" panel. Then select Armature and click the "Test" button again. It correctly creates the rigid body on the new cube.

Now select Cube and click the "Test" button in the "Test Properties" panel. Then select Armature and click the "Test" button again. It *incorrectly* creates the rigid body on the old cube, and it gives an error.

So Blender's internal context is incorrect when the panel is inside of the Properties, since it works correctly when the panel is outside of the Properties. Therefore there is a bug in Blender.

@Pauan (Pauan) I haven't checked first example, because you mentioned that you get context is incorrect error, so I focused on overriding context.

This reminds me of T80431, but my example kinda disproves that. At least I think. I will have to look into this to see what happens here exactly.