PLY import fails when called during frame_change_pre handler #85770

Open
opened 2021-02-18 16:58:25 +01:00 by Justin Jensen · 11 comments

System Information
Operating system: Windows 10, Kubuntu 18.10
Graphics card:

Blender Version
Broken:
2.91.0, 2.91.2 (see https:*developer.blender.org/rBA089cfd12a5511829aafad3790417a5218955a3ad)
Worked:
2.83.12

Short description of error
When the PLY importer is called during the frame_change_pre handler, the import fails with the following message:

context.window.cursor_set('WAIT')
AttributeError: 'NoneType' object has no attribute 'cursor_set'```

**Exact steps for others to reproduce the error**
This error is specific to users of the [Stop Motion OBJ ](https://github.com/neverhood311/Stop-motion-OBJ) addon.
I've had two reports of users trying to import a sequence of .PLY files using the [Streaming Sequence ](https://github.com/neverhood311/stop-motion-obj/wiki#import-a-largelong-sequence) feature, and having the addon fail when it tries to import the next mesh into the cache, but only while rendering the sequence.


I think this might be due to a recent patch to the importer (see [https:*developer.blender.org/rBA089cfd12a5511829aafad3790417a5218955a3ad](https:*developer.blender.org/rBA089cfd12a5511829aafad3790417a5218955a3ad)), which sets the cursor type on the current context's window. However, while the animation is rendering, apparently the cursor is not available, and throws an error. The current workaround is to use Blender 2.83 instead of Blender 2.91.

Would it be possible to check whether the context has a window with a cursor before calling `context.window.cursor_set('WAIT')`? Something like:
```if hasattr(context.window, 'cursor_set'):
context.window.cursor_set('WAIT')```
**System Information** Operating system: Windows 10, Kubuntu 18.10 Graphics card: **Blender Version** Broken: 2.91.0, 2.91.2 (see [https:*developer.blender.org/rBA089cfd12a5511829aafad3790417a5218955a3ad](https:*developer.blender.org/rBA089cfd12a5511829aafad3790417a5218955a3ad)) Worked: 2.83.12 **Short description of error** When the PLY importer is called during the frame_change_pre handler, the import fails with the following message: ```File "/<path/to/blender>/blender-2.91.0-linux64/2.91/scripts/addons/io_mesh_ply/init.py", line 87, in execute context.window.cursor_set('WAIT') AttributeError: 'NoneType' object has no attribute 'cursor_set'``` **Exact steps for others to reproduce the error** This error is specific to users of the [Stop Motion OBJ ](https://github.com/neverhood311/Stop-motion-OBJ) addon. I've had two reports of users trying to import a sequence of .PLY files using the [Streaming Sequence ](https://github.com/neverhood311/stop-motion-obj/wiki#import-a-largelong-sequence) feature, and having the addon fail when it tries to import the next mesh into the cache, but only while rendering the sequence. I think this might be due to a recent patch to the importer (see [https:*developer.blender.org/rBA089cfd12a5511829aafad3790417a5218955a3ad](https:*developer.blender.org/rBA089cfd12a5511829aafad3790417a5218955a3ad)), which sets the cursor type on the current context's window. However, while the animation is rendering, apparently the cursor is not available, and throws an error. The current workaround is to use Blender 2.83 instead of Blender 2.91. Would it be possible to check whether the context has a window with a cursor before calling `context.window.cursor_set('WAIT')`? Something like: ```if hasattr(context.window, 'cursor_set'): ``` context.window.cursor_set('WAIT')```
Author

Added subscriber: @JustinJensen

Added subscriber: @JustinJensen

Added subscriber: @t.schumacher77

Added subscriber: @t.schumacher77
Author

This is still an issue in Blender 2.93.6

I suggested a simple fix in my bug report above.

This is still an issue in Blender 2.93.6 I suggested a simple fix in my bug report above.
Member

Added subscriber: @OmarEmaraDev

Added subscriber: @OmarEmaraDev
Member

Changed status from 'Needs Triage' to: 'Needs User Info'

Changed status from 'Needs Triage' to: 'Needs User Info'
Member

I can't replicate this with the following code snippet:

bpy.app.handlers.frame_change_pre.append(lambda _:  bpy.ops.export_mesh.ply(filepath = "/tmp/test.ply"))

Should I have done something differently?

I can't replicate this with the following code snippet: ``` bpy.app.handlers.frame_change_pre.append(lambda _: bpy.ops.export_mesh.ply(filepath = "/tmp/test.ply")) ``` Should I have done something differently?
Author

Thanks for taking a look at this.

My addon calls bpy.ops.import_mesh.ply() (see https:*github.com/neverhood311/Stop-motion-OBJ/blob/v2.2.0.alpha.18/src/stop_motion_obj.py#L304)
In your code snipped, it looks like you're calling export_mesh()

Thanks for taking a look at this. My addon calls `bpy.ops.import_mesh.ply()` (see [https:*github.com/neverhood311/Stop-motion-OBJ/blob/v2.2.0.alpha.18/src/stop_motion_obj.py#L304](https:*github.com/neverhood311/Stop-motion-OBJ/blob/v2.2.0.alpha.18/src/stop_motion_obj.py#L304)) In your code snipped, it looks like you're calling `export_mesh()`
Member

import_mesh seems to work as well here.

But regardless, when an operation like this uses a context element that might not be available, like the window in this case, usually what you do is override the window member of the context with any window. See https://docs.blender.org/api/current/bpy.ops.html#overriding-context.

However, regardless, I think the PLY add-on should put a condition on that in case it gets executed in a window-less environment as you suggested.

if context.window:
    context.window.cursor_set('WAIT')

I am not sure if such a patch would be accepted. But you seem familiar enough, so why don't you try to create a patch to fix this? https://wiki.blender.org/wiki/Process/Contributing_Code

`import_mesh` seems to work as well here. But regardless, when an operation like this uses a context element that might not be available, like the window in this case, usually what you do is override the window member of the context with any window. See https://docs.blender.org/api/current/bpy.ops.html#overriding-context. However, regardless, I think the PLY add-on should put a condition on that in case it gets executed in a window-less environment as you suggested. ``` if context.window: context.window.cursor_set('WAIT') ``` I am not sure if such a patch would be accepted. But you seem familiar enough, so why don't you try to create a patch to fix this? https://wiki.blender.org/wiki/Process/Contributing_Code
Member

Changed status from 'Needs User Info' to: 'Confirmed'

Changed status from 'Needs User Info' to: 'Confirmed'

Added subscriber: @oystelan

Added subscriber: @oystelan

Dear Justin and Omar,
I stumbled upon this problem aswell when using an addon similar to stop-motion-obj. I managed to overcome the problem by modifying the following two functions in the import_ply scripts:

in init.py (line 65):

    def execute(self, context):
        import os
        from . import import_ply

        if hasattr(context.window, 'cursor_set'): # context.window is not accessible during rendering
            context.window.cursor_set('WAIT')

        paths = [
            os.path.join(self.directory, name.name)
            for name in self.files
        ]

        if not paths:
            paths.append(self.filepath)

        for path in paths:
            import_ply.load(self, context, path)

        if hasattr(context.window, 'cursor_set'):  # context.window is not accessible during rendering
            context.window.cursor_set('DEFAULT')

        return {'FINISHED'}

and in import_ply.py (line 413):

def load_ply(filepath):
    import time
    import bpy

    t = time.time()
    ply_name = bpy.path.display_name_from_filepath(filepath)

    mesh = load_ply_mesh(filepath, ply_name)
    if not mesh:
        return {'CANCELLED'}

    if hasattr(bpy.context, 'selected_objects'):  # context.select_objects is not accessible during rendering
        for ob in bpy.context.selected_objects:
            ob.select_set(False)

    obj = bpy.data.objects.new(ply_name, mesh)
    bpy.context.collection.objects.link(obj)
    bpy.context.view_layer.objects.active = obj
    obj.select_set(True)

    print("\nSuccessfully imported %r in %.3f sec" % (filepath, time.time() - t))

    return {'FINISHED'}

This may not be a perfect fix, but it seems to work (tested in blender 3.3).

Dear Justin and Omar, I stumbled upon this problem aswell when using an addon similar to stop-motion-obj. I managed to overcome the problem by modifying the following two functions in the import_ply scripts: in __init__.py (line 65): ``` def execute(self, context): import os from . import import_ply if hasattr(context.window, 'cursor_set'): # context.window is not accessible during rendering context.window.cursor_set('WAIT') paths = [ os.path.join(self.directory, name.name) for name in self.files ] if not paths: paths.append(self.filepath) for path in paths: import_ply.load(self, context, path) if hasattr(context.window, 'cursor_set'): # context.window is not accessible during rendering context.window.cursor_set('DEFAULT') return {'FINISHED'} ``` and in import_ply.py (line 413): ``` def load_ply(filepath): import time import bpy t = time.time() ply_name = bpy.path.display_name_from_filepath(filepath) mesh = load_ply_mesh(filepath, ply_name) if not mesh: return {'CANCELLED'} if hasattr(bpy.context, 'selected_objects'): # context.select_objects is not accessible during rendering for ob in bpy.context.selected_objects: ob.select_set(False) obj = bpy.data.objects.new(ply_name, mesh) bpy.context.collection.objects.link(obj) bpy.context.view_layer.objects.active = obj obj.select_set(True) print("\nSuccessfully imported %r in %.3f sec" % (filepath, time.time() - t)) return {'FINISHED'} ``` This may not be a perfect fix, but it seems to work (tested in blender 3.3).
Sign in to join this conversation.
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#85770
No description provided.