Joining objects results in an error #112218

Closed
opened 2023-09-11 09:26:52 +02:00 by Robin-Hogerhuis · 5 comments

System Information
Operating system: Windows 10 Enterprise
Graphics card: NVIDIA Quadro K600 and NVIDIA GeForce GT 610 (for two monitor setup)

Blender Version
Broken: 3.5.1, hash: e1ccd9d4a1

Short description of error
RuntimeError: Operator bpy.ops.object.join.poll() failed, context is incorrect

Exact steps for others to reproduce the error
I execute my python file from Visual Studio Code to Blender. I have followed this tutorial to accomplish this: https://www.youtube.com/watch?v=YUytEtaVrrc. I get the error when trying to join all meshes of my imported gltf object.

In specific
I'm trying to join multiple meshes of my imported GLTF object. This object consists of multiple meshes/parts and I want to join them via the python API to know the complete dimensions of the joined object. When trying to do this with code it didn't work and I got the above message. To test further I tried to join all objects in my scene as a simpler use case. But, I still got the same error. Thirdly, I tried to join the objects in Blender directly by using 'a' -> 'ctrl + j'. What I found are some inconsistencies. When trying it, sometimes it works and sometimes it doesn't. I often get it working when deselecting and selecting everything and trying it again until it works. See code for more specifics.

Goal
I'm trying to join all meshes within my loaded GLTF object. But, it seems that there is a bug within Blender that stops me from doing this.

Code

def load_gltf_object(filepath: str) -> None:
   # Import gltf object 
   bpy.ops.import_scene.gltf(filepath=filepath)

   # Select all objects for a simpler use case 
   bpy.ops.object.select_all(action='SELECT')

   # Join all objects 
   bpy.ops.object.join()

load_gltf_object(filepath)

**System Information** Operating system: Windows 10 Enterprise Graphics card: NVIDIA Quadro K600 and NVIDIA GeForce GT 610 (for two monitor setup) **Blender Version** Broken: 3.5.1, hash: e1ccd9d4a1d3 **Short description of error** `RuntimeError: Operator bpy.ops.object.join.poll() failed, context is incorrect` **Exact steps for others to reproduce the error** I execute my python file from Visual Studio Code to Blender. I have followed this tutorial to accomplish this: https://www.youtube.com/watch?v=YUytEtaVrrc. I get the error when trying to join all meshes of my imported gltf object. **In specific** I'm trying to join multiple meshes of my imported GLTF object. This object consists of multiple meshes/parts and I want to join them via the python API to know the complete dimensions of the joined object. When trying to do this with code it didn't work and I got the above message. To test further I tried to join all objects in my scene as a simpler use case. But, I still got the same error. Thirdly, I tried to join the objects in Blender directly by using 'a' -> 'ctrl + j'. What I found are some inconsistencies. When trying it, sometimes it works and sometimes it doesn't. I often get it working when deselecting and selecting everything and trying it again until it works. See code for more specifics. **Goal** I'm trying to join all meshes within my loaded GLTF object. But, it seems that there is a bug within Blender that stops me from doing this. **Code** ```python def load_gltf_object(filepath: str) -> None: # Import gltf object bpy.ops.import_scene.gltf(filepath=filepath) # Select all objects for a simpler use case bpy.ops.object.select_all(action='SELECT') # Join all objects bpy.ops.object.join() load_gltf_object(filepath) ```
Robin-Hogerhuis added the
Priority
Normal
Type
Report
Status
Needs Triage
labels 2023-09-11 09:26:53 +02:00
Member

object.join requires there's at least an active window and screen, so you probably need to find an active screen and use it as a context override. Try doing this:

wnd=bpy.data.window_managers[0].windows[0]
scr=bpy.data.screens[0]
with bpy.context.temp_override(window=wnd,screen=scr):
    bpy.ops.object.join()

After some digging I don't think I have seen any of the window/screen being referenced in the join function, nor does any of the called ones inside there, so I'm not quite sure why that's needed. The related bits in object_join_poll doesn't seem to have changed in at least 4 years, I think it's technically safe to not require a window and screen.

`object.join` requires there's at least an active window and screen, so you probably need to find an active screen and use it as a context override. Try doing this: ``` wnd=bpy.data.window_managers[0].windows[0] scr=bpy.data.screens[0] with bpy.context.temp_override(window=wnd,screen=scr): bpy.ops.object.join() ``` After some digging I don't think I have seen any of the window/screen being referenced in the join function, nor does any of the called ones inside there, so I'm not quite sure why that's needed. The related bits in `object_join_poll` doesn't seem to have changed in at least 4 years, I think it's technically safe to not require a window and screen.
YimingWu added
Module
Modeling
Status
Needs Info from Developers
and removed
Status
Needs Triage
labels 2023-09-11 10:07:24 +02:00
Member

Looks like there are Empties involved in the join operation (e.g. the Sketchfab nmodel object)

It would be normal that the operation is cancelled in this case
So to get that out of the way, does it work for you if you substitute

bpy.ops.object.select_all(action='SELECT')

with

bpy.ops.object.select_by_type(type='MESH') ?

Looks like there are Empties involved in the join operation (e.g. the `Sketchfab nmodel` object) It would be normal that the operation is cancelled in this case So to get that out of the way, does it work for you if you substitute `bpy.ops.object.select_all(action='SELECT')` with `bpy.ops.object.select_by_type(type='MESH')` ?

@ChengduLittleA , Thank you for your reply. I have tried to manually set the active window and screen with your code, but the error still occurs.

@lichtwerk. Also thank you for your reply. I have tried it before by only selecting the meshes indeed, but no luck then. But I tried it again with your code and still got the same error.

Also I have tried both your ideas combined for testing sake but still received the same error. To maybe replicate the same error this is the object I'm currently testing with (see uploaded file)

@ChengduLittleA , Thank you for your reply. I have tried to manually set the active window and screen with your code, but the error still occurs. @lichtwerk. Also thank you for your reply. I have tried it before by only selecting the meshes indeed, but no luck then. But I tried it again with your code and still got the same error. Also I have tried both your ideas combined for testing sake but still received the same error. To maybe replicate the same error this is the object I'm currently testing with (see uploaded file)
Member

From testing your file and script, it's likely that you don't have an active object as mesh at the time of importing.

Thus you will need to manually find and assign an active_object as context override as well:

def load_gltf_object(filepath: str) -> None:
    # Import gltf object 
    bpy.ops.import_scene.gltf(filepath=filepath)

    # Select all objects for a simpler use case 
    bpy.ops.object.select_all(action='SELECT')

    # Join all objects 
    wnd=bpy.data.window_managers[0].windows[0]
    scr=bpy.data.screens[0]
    obj=None
    for ob in bpy.data.objects:
        if ob.type=='MESH':
            obj=ob
            break
    if obj is None:
        return
    
    with bpy.context.temp_override(window=wnd,screen=scr,active_object=obj):
        bpy.ops.object.join()

It should not require window and screen to be present, I will make a patch to get rid of that part.

From testing your file and script, it's likely that you don't have an active object as mesh at the time of importing. Thus you will need to manually find and assign an `active_object` as context override as well: ``` def load_gltf_object(filepath: str) -> None: # Import gltf object bpy.ops.import_scene.gltf(filepath=filepath) # Select all objects for a simpler use case bpy.ops.object.select_all(action='SELECT') # Join all objects wnd=bpy.data.window_managers[0].windows[0] scr=bpy.data.screens[0] obj=None for ob in bpy.data.objects: if ob.type=='MESH': obj=ob break if obj is None: return with bpy.context.temp_override(window=wnd,screen=scr,active_object=obj): bpy.ops.object.join() ``` It _should_ not require window and screen to be present, I will make a patch to get rid of that part.

@ChengduLittleA , thank you very much. I tested it and it works!!

@ChengduLittleA , thank you very much. I tested it and it works!!
Blender Bot added
Status
Resolved
and removed
Status
Needs Info from Developers
labels 2023-09-11 15:54:38 +02:00
Robin-Hogerhuis changed title from Joining objects results in an error to Joining objects results in an error 2023-09-21 14:05:04 +02:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 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#112218
No description provided.