Incorrect Context Error when importing Alembic files

Hi, I have been stuck at trying to import Alembics via my plugin. I keep getting the Context is incorrect error. I have followed all of the methods that are available here.

I have tried the following solutions:

  1. Change Area.Type
  2. Override Context
  3. Low-level
  4. Specify the right context (I did that after trying to run the Poll() operation for each context)

But nothing is working and the error persists. According to documentation this is how alembics are imported via python:
bpy.ops.wm.alembic_import(filepath=meshPath)

The above line of code works fine in the command line and the script editor but it is not working in the plugin. Any help would be greatly appreciated!

[Update 1]
The bpy.context.area is None so I cannot really Override the context either because I was using the following way of overriding the context:
original_type = bpy.context.area.type
bpy.context.area.type = “VIEW_3D”
bpy.ops.wm.alembic_import(filepath=meshPath, as_background_job=False)
bpy.context.area.type = original_type

[Update 2] The following properties are all None.
bpy.context.area = None
bpy.context.gizmo_group = None
bpy.context.region = None
bpy.context.region_data = None
bpy.context.screen = None
bpy.context.space_data = None
bpy.context.window = None
bpy.context.workspace = None

[Update 3] Stripped down code of the plugin (Though I should mention importing directly in the operator throws some other errors but it does work in the operator.):

import bpy, os, time, socket, threading

bl_info = {
    "name": "Import Helper",
    "description": "Let's blender import goemetry",
    "author": "Ajwad",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "File > Import",
    "warning": "", # used for warning icon and text in addons panel
    "wiki_url": "https://docs.google.com/document/",
    "tracker_url": "https://docs.google.com/document/",
    "support": "COMMUNITY",
    "category": "Import-Export"
}


class Import_Processor():

    def __init__(self):
        self.importMesh()
    
    def importMesh(self):
        try:
            meshPath = "C:\\Users\\PC\\Desktop\\box.abc" # Path to the alembc file.
            bpy.ops.wm.alembic_import(filepath=meshPath, as_background_job=False)
        except Exception as e:
            print( "Error: ", str(e) )

class ms_Init(threading.Thread):

    def __init__(self, importer):
        threading.Thread.__init__(self)
        self.importer = importer

	#Start the thread to start listing to the port.
    def run(self):
        try:
            run_livelink = True
            host, port = 'localhost', 28888
            socket_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            socket_.bind((host, port))

            while run_livelink:
                socket_.listen(5)
                client, addr = socket_.accept()
                data = ""
                buffer_size = 4096*2 
                data = client.recv(buffer_size)
                if data != "":
                    self.TotalData = b""
                    self.TotalData += data
                    while run_livelink:
                        data = client.recv(4096*2)
                        if data : self.TotalData += data
                        else:
                            self.importer(self.TotalData)
                            break
        except Exception as e:
            print( "Error: ", str(e) )

class IMPORTHELPER_OT_import(bpy.types.Operator):

    bl_idname = "importhelper.import"
    bl_label = "Import Helper"

    def execute(self, context):

        try:
            self.thread_ = threading.Thread(target = self.socketMonitor)
            self.thread_.start()
            return {'FINISHED'}
        except Exception as e:
            print( "Error: ", str(e) )
            return {"FAILED"}


    def socketMonitor(self):
        try:
            threadedServer = ms_Init(self.importer)
            threadedServer.start()
        except Exception as e:
            print( "Error: ", str(e) )
            return {"FAILED"}

    def importer (self, recv_data):
        try:
            Import_Processor()
        except Exception as e:
            print( "Error: ", str(e) )
            return {"FAILED"}

def menu_func_import (self, context):
    self.layout.operator(IMPORTHELPER_OT_import.bl_idname, text="Import helper plugin")

def register():
    bpy.utils.register_class(IMPORTHELPER_OT_import)
    bpy.types.TOPBAR_MT_file_import.append(menu_func_import)

def unregister():
    bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)

if __name__ == "__main__":

The second class that sends dummy data over socket. You can install a VS code extension called “Code Runner” by “Jun Han” to run this script once the plugin is installed in blender and you started the plugin by going to: File > Import > Import helper plugin

import sys, socket

host, port = 'localhost', 28888 
    
final_data = "dummydata"

# Create the socket & send the request
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.sendall(bytes(final_data, encoding='utf-8'))
s.close()

You can get the box alembic from here: https://drive.google.com/file/d/1K2vlb929YZihsx_294LRpE6BdHPyXHX_/

Thanks!

Hi,

Your title says "Incorrect Context Error when importing Alembic files " but did you try another import (like obj) to make sure that it comes specifically from Alembic import ?

The fact that it works for you in console or script, but not from your plugin, makes me think that the problem is not due to Alembic import, but due to your plugin having bad context before you call bpy.ops.wm.alembic_import(filepath=meshPath)

In addition as you said in your [Update2], bpy.context looks totally broken, so it must have nothing to do with Alembic Importer :stuck_out_tongue:

But I didn’t have a look on you code, so it’s hard to really help

See you :slight_smile: ++
Tricotou

1 Like

Hi Tricotou,

Thank you for replying and importing FBX and OBJ files is working fine. It is just that incorrect context exception is raised when I try importing the Alembics.

I know context is broken but I cannot figure out the cause of that.

Best,
Ajwad

bpy.ops.wm.alembic_import(filepath=mesh_path) should just work. Without knowing more about the surrounding code there is little we can do to help. Can you post a minimal example that demonstrates this issue?

Having a minimal example helps in two ways. Firstly, and most importantly, it allows you to drill down to the actual problem, by removing all bits of code that have nothing to do with it. By trimming down the code to the bare minimum, it’s often much clearer what the cause of the problem is. Secondly, it helps us outsiders to quickly analyse the code, without having to spend time understanding code that turns out to be irrelevant. This ensures that we can help efficiently.

1 Like

Hi,

Thank you for getting back to me. I just updated the original post with how I am trying to import alembics. :slight_smile:

Best,
Ajwad

The code as it is now doesn’t run. It uses self.json_Array, which is undefined. Please, make it possible for us to help you, and provide code that allows us to see your problem for ourselves.

PS: I’ve updated your original post by surrounding the code with triple backticks (```), which marks it as code and improves readability.

Hi again,

I have updated the code and attached a test alembic file but feel free to use your own alembic file just don’t forget to change the alembic file path in the code though. Thanks!

I tried to run the code, but it won’t register as an add-on. I get this error:

Exception in module register(): /home/sybren/.config/blender/2.82/scripts/addons/alembic_test.py
Traceback (most recent call last):
  File "/home/sybren/workspace/blender-git/build_linux/bin/2.82/scripts/modules/addon_utils.py", line 384, in enable
    mod.register()
  File "/home/sybren/.config/blender/2.82/scripts/addons/alembic_test.py", line 45, in register
    bpy.utils.register_class(StartPlugin)
RuntimeError: Error: Registering operator class: 'StartPlugin', invalid bl_idname 'CustomPlugin.py', at position 0

I renamed the StartPlugin class to IMPORTHELPER_OT_import, set its bl_idname = "importhelper.import" (Blender naming convention), and renamed the MenuImport function to menu_import (Python naming convention), and now it works. I can’t reproduce the error you’re getting.

Which version of Blender are you using?

Hi again, thank you for getting back to me.

I am using Blender 2.8 and I can see directly calling the import method from the operator works but since I stripped down the original class from the plugin so I removed the threading code as well. It seems the issue is only there when I call the same method from thread. I think the problem is that after the operator’s execute method is finished it destroy’s it’s context property. Is there any way to keep it running or in the memory?

I have updated the original post to add the threading code and also a helper class that sends dummy data to that thread.

Thanks :slight_smile:

And there is your problem. The Blender API is not thread-safe, and should only be called from the main thread.

Ahh bummer! Anyway thanks for the help and have a great weekend! :+1: