Having trouble with the bpy.ops.join() function

Hello everyone,

I made a python script to create a geometric mesh from scratch. In this script at one point, I use the function bpy.ops.join() to join several meshes.

It was a struggle to make it work, but I finally did it after thoroughly learning how to use the library.
The context is the following:

  • I have a mesh object in OBJECT mode that is both the bpy.context.view_layer.objects.active object and one of the bpy.context.view_layer.objects.selected objects.
  • I have a set of other mesh objects that are in the bpy.context.view_layer.objects.selected objects.

When I run the script, everything works correctly. The problem comes when I try to render it.
To make things clear, I want the shape of my mesh to change at every frame in a quite complex way that cannot be done with interpolation (the only way that I found until now). So the method that I want to try is to rebuild my mesh from scratch at every frame. The solution that I have in order to do this is to delete the previous frame’s mesh object and create a new one at the beginning of each frame with bpy.app.handlers.frame_change_pre.append().
When I do that, everything in my code works excepted bpy.ops.join().
I print the values of the context that I mentioned earlier wich are identical when I run the script and when I try to render the scene.

Does anyone have a clue of what in the context might change when I try to render the scene that prevents me from using the join() function ?

Any hint would be much appreciated.

When I run this function from a script, it works well. I set an active object, selected objects, and am in “OBJECT” mode. My meshes are merged into one mesh.

The problem happens when I try to do the exact same operation in the same function when rendering. I get an error that tells me the context is incorrect without further detail. I can’t find any information on the subject. Do you know if something in the context changes that provides me from using this function ?

This operator relies on the objects being correctly selected / activated in the current context. You can override it with a custom list of objects :

active_object = bpy.data.objects["Cube"]  # or whatever object you want
selected_objects = [
with bpy.context.temp_override(active_object=active_object, selected_objects=selected_objects):