Numerous problems with the new bpy.ops.uv.pack_islands() operator

Firstly, I’m sorry if this is the wrong place to post. I don’t know where to ask questions like this now that the specific Python API forum has been set to archive.

I am trying to update my Blender addon to take advantage of the new UV packing in Blender 3.6. I am having numerous problems with the new bpy.ops.uv.pack_islands() operator. I’m hoping someone can give me a steer.

PROBLEM 1 – If you call the operator with the old arguments (as many existing scripts will), Blender will hang and then crash. This doesn’t seem like correct behavior. For example, merely executing this in the Blender terminal will cause Blender to crash for me:

bpy.ops.uv.pack_islands(rotate=True, margin=0.1)

That doesn’t seem right, but I thought I could work around it. Enter….

PROBLEM 2 – Calling this operator, even with the correct arguments, is no longer blocking. As such, I now have the issue where my script calls bpy.ops.uv.pack_islands, and then proceeds to plough into a bunch of context incorrect errors for the code that comes after it as bpy.ops.uv.pack_islands is still trying to complete.

Previously, I have called bpy.ops.uv.pack_islands from inside another operator. However, my script is actually a big Macro, so I had the bright idea to make bpy.ops.uv.pack_islands an operator in the Macro in its own right. That should have allowed it to finish without before executing the next operator in the Macro (at least, that’s how it works with every other operator).

op = MACRO.define(UV_OT_pack_islands)
op.properties.udim_source= sbp.uvp_pack_to
etc.
etc.

However, that led to…

PROBLEM 3 – Merely adding bpy.ops.uv.pack_islands to a Macro causes a context incorrect error when trying to run that Macro. It seems that just its mere presence as one of the Marco operators means that the Macro no longer runs at all.

Really hoping someone can point me in the right direction. Appreciate any help.

Hi Lewis2e,

Thanks for your report, and my apologies for the bugs you’re encountering there.

For your first problem, we’re tracking that one over at #108171 - Operator bpy.ops.uv.pack_islands call leads to Blender crash - blender - Blender Projects and it will be fixed in Blender 3.6.1

For Problem 2, the operator should indeed by blocking when called from scripts. I’m not sure what’s going on there and will investigate further.

Similarly problem 3, again not sure what’s happening and I’ll investigate.

In the interim, if you need to make progress, you could try using the nightly build for Blender 4.0, where the first bug is fixed, and see if that helps.

Apologies,
–Chris

2 Likes

Hi @Chris_Blackbourn

Thank you for your reply. I very much appreciate it.

You’re right, #108171 sounds like it’s my core issue. I also raised my own bug report too before I realised that this one existed. Great to know that it’s shortly going to be fixed.

I can work around Problem 2 by using a modal, but yes it would be great if the operator was blocking again.

For problem 3, I’ve done some more investigations. I can work around this by having the script switch to edit mode, call the macro, and then switch back to object mode.

I don’t know if you consider this correct behaviour or not. Obviously, bpy.ops.uv.pack_islands will eventually require edit mode, but it’s only one of a series of operators queued up in the macro. I wouldn’t have thought that the macro would have to meet the start conditions of every operator in the queue before it would run… but – again – maybe this is correct behaviour? I am not sure.

Thank you again for your reply and for looking into this further.

@Chris_Blackbourn - Just to say that I’ve been experimenting with Blender 4.0 and, while the crash is fixed, the operator still appears to be non-blocking. I suspect that will screw up a few different addons, not just SimpleBake.

Many thanks

Hi @Chris_Blackbourn

The problem is that the new packing operator is modal. This makes it impossible to use it inside macros or addons because the addon does not know when the modal operator will finish and after the bpy.ops.uv.pack_islands() command continues to execute the code below. The situation arises when the packing and the addon code are executed in parallel. This leads to errors and cases similar to “context incorrect”.

Checking on this and from what I can see calling the pack operator from Python is blocking, the issue is that your calling the operator from a macro.

Could you check if this resolves the problem?

diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc
index 31a2b423b9d..865c71fd134 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc
@@ -1487,7 +1487,8 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
 
   UVPackIslandsData *pid = static_cast<UVPackIslandsData *>(
       MEM_callocN(sizeof(UVPackIslandsData), "pack_islands_data"));
-  pid->use_job = op->flag & OP_IS_INVOKE;
+  /* Block when running from a macro because other operators must wait for this to finish. */
+  pid->use_job = (op->flag & OP_IS_INVOKE) && (op->opm == NULL);
   pid->scene = scene;
   pid->objects = objects;
   pid->objects_len = objects_len;

@ideasman42 - Thanks for this. Unfortunately, it doesn’t seem to make any difference. I still get context incorrect errors from every operator call that comes after bpy.ops.uv.pack_islands implying that it isn’t blocking.

In honesty, it’s my first time compiling Blender so I can’t 100% guarantee that I haven’t done something wrong. I did apply the diff before building and I manually checked uvedit_unwrap_ops.cc to make sure it was properly applied. So I am as sure as I can be that I did it correct.

I am calling the unwrap operator from within my own operator which is part of a macro (if that makes sense?). So Macro->My Operator->call to bpy.ops.uv.pack_islands(). Previously (<3.6) this would have been blocking.

I can work around this issue by making my own operator a modal that keeps checking for bpy.ops.uv.pack_islands to finish. This is blocking but feels very hacky.