1

I want to UV Unwrap with Smart UV Project but don't want to use bpy.ops.uv.smart_project().

In Blender 3.6 LTS, I tried with context.temp_override() but got this error:

import bpy
from bpy import context

override = context.copy() override['mode'] = 'EDIT_MESH' override['selected_objects'] = [bpy.data.objects['Cube'], bpy.data.objects['Suzanne']] # will replace with another list of objects

with context.temp_override(**override): bpy.ops.uv.smart_project(angle_limit=1.15192, margin_method='SCALED', island_margin=0, area_weight=0, correct_aspect=True, scale_to_bounds=False)

RuntimeError: Operator bpy.ops.uv.smart_project.poll() failed, context is incorrect

Karan
  • 1,984
  • 5
  • 21
  • It's strange. The script worked fine for me with the same version of Blender. You are in Edit Mode? – tetii Jul 28 '23 at 06:07
  • https://blender.stackexchange.com/questions/296981/different-result-when-executing-bpy-ops-uv-smart-project-versus-doing-manually-i/296985#296985 – Harry McKenzie Jul 28 '23 at 06:27
  • btw usage of override=context.copy() i think is deprecated. https://blender.stackexchange.com/questions/6101/poll-failed-context-incorrect-example-bpy-ops-view3d-background-image-add – Harry McKenzie Jul 28 '23 at 06:35
  • @tetii Yes it works in Edit mode, but I want it in Object mode. I also tried using override['mode'] = 'EDIT_MESH' – Karan Jul 28 '23 at 07:30
  • don't use override = context.copy() that is deprecated. use override = {}. that will work in edit mode. bmesh doesnt have a direct uv unwrap method. I don't think you can avoid going into Edit mode. – Harry McKenzie Jul 28 '23 at 11:31
  • yes, but override = context.copy() get a copy of the context as dict. So I don't have to fill the dict if I use override = {}. – Karan Jul 28 '23 at 21:10
  • yeah but thats causing error because it is deprecated since version 3.2. deprecated means that the code no longer supports this. now the proper way is not to pass a context copy of object – Harry McKenzie Jul 28 '23 at 23:23

1 Answers1

0

You are in the wrong context. Your context is in Object Mode but you need to be in Edit Mode. Here is the working script:

import bpy

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

selected_objects = [bpy.data.objects['Cube'], bpy.data.objects['Suzanne']]

for obj in selected_objects: obj.select_set(True)

area_type = 'VIEW_3D' areas = [area for area in bpy.context.window.screen.areas if area.type == area_type]

if len(areas) <= 0: raise Exception(f"Make sure an Area of type {area_type} is open or visible in your screen!")

with bpy.context.temp_override( window=bpy.context.window, area=areas[0], regions=[region for region in areas[0].regions if region.type == 'WINDOW'][0], screen=bpy.context.window.screen ): bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.smart_project(angle_limit=1.15192, margin_method='SCALED', island_margin=0, area_weight=0, correct_aspect=True, scale_to_bounds=False)

EDIT: Oh we don't even need to do any context overrides still works:

import bpy

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

selected_objects = [bpy.data.objects['Cube'], bpy.data.objects['Suzanne']]

for obj in selected_objects: obj.select_set(True)

bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.smart_project(angle_limit=1.15192, margin_method='SCALED', island_margin=0, area_weight=0, correct_aspect=True, scale_to_bounds=False)

Harry McKenzie
  • 10,995
  • 8
  • 23
  • 51