1
$\begingroup$

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

$\endgroup$
7
  • $\begingroup$ It's strange. The script worked fine for me with the same version of Blender. You are in Edit Mode? $\endgroup$
    – tetii
    Jul 28, 2023 at 6:07
  • $\begingroup$ blender.stackexchange.com/questions/296981/… $\endgroup$ Jul 28, 2023 at 6:27
  • $\begingroup$ btw usage of override=context.copy() i think is deprecated. blender.stackexchange.com/questions/6101/… $\endgroup$ Jul 28, 2023 at 6:35
  • $\begingroup$ @tetii Yes it works in Edit mode, but I want it in Object mode. I also tried using override['mode'] = 'EDIT_MESH' $\endgroup$
    – Karan
    Jul 28, 2023 at 7:30
  • $\begingroup$ 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. $\endgroup$ Jul 28, 2023 at 11:31

1 Answer 1

0
$\begingroup$

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)
$\endgroup$
2
  • $\begingroup$ I don't want to use bpy.ops, any better Python way? I also tried using override['mode'] = 'EDIT_MESH' $\endgroup$
    – Karan
    Jul 28, 2023 at 7:24
  • $\begingroup$ Is it possible to do with bmesh? $\endgroup$
    – Karan
    Jul 28, 2023 at 7:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .