Петля не работает, трехстрочный код Python

этот вопрос о blender, скриптах на python

Я совершенно новичок в этом, поэтому, пожалуйста, извините меня за любой глупый вопрос / комментарий новичка.

Я сделал это простым (3 строки кода), чтобы облегчить решение проблемы.

мне нужен код, который добавляет новую ультрафиолетовую карту для каждого объекта в функции цикла.

Но этот код вместо этого добавляет несколько новых UV-карт только к одному объекту.

import bpy
for x in bpy.context.selected_objects:
    bpy.ops.mesh.uv_texture_add()

что не так я здесь делаю??

Спасибо

3 ответа

Решение

uv_texture_add Оператор - это оператор, который работает только с текущим активным объектом. Вы можете изменить активный объект, установив scene.objects.active

import bpy
for x in bpy.context.selected_objects:
    bpy.context.scene.objects.active = x
    bpy.ops.mesh.uv_texture_add()

Подобно тому, что сказал Самблер, я всегда использую:

for active in bpy.context.selected_objects:
    bpy.context.scene.objects.active = active
    ...

Эти две строки я использую больше, чем какие-либо другие при программировании для Blender (кроме import bpy конечно).

Я думаю, что впервые узнал об этом здесь, если вы хотите хорошее вступление о том, как это работает:

https://cgcookiemarkets.com/2014/12/11/writing-first-blender-script/

В статье он использует:

# Create a list of all the selected objects
selected = bpy.context.selected_objects

# Iterate through all selected objects
for obj in selected:
    bpy.context.scene.objects.active = obj
    ...

Его комментарии объясняют это довольно хорошо, но я сделаю еще один шаг вперед. Как вы знаете, в Blender отсутствует встроенное редактирование нескольких объектов, поэтому вы выбрали объекты и один активный объект. Активный объект - это то, что вы можете редактировать, если попытаетесь установить его значения из python или самого графического интерфейса Blender. Поэтому, хотя мы каждый раз пишем это немного по-разному, эффект тот же. Мы перебираем все выбранные объекты с помощью for active in bpy.context.selected_objectsЗатем мы устанавливаем активный объект следующим в цикле, который перебирает все объекты, выбранные с помощью bpy.context.scene.objects.active = active, В результате, все, что мы делаем в цикле, выполняется один раз для каждого объекта в выделении, и любая операция, которую мы делаем с рассматриваемым объектом, выполняется над всеми объектами. Что бы произошло, если бы мы использовали только первую строку и поместили наш код в for цикл?

for active in bpy.context.selected_objects:
    ...

Что бы мы ни делали в цикле, это делается один раз для каждого объекта в выделении, но любая операция, которую мы делаем с данным объектом, выполняется только с активным объектом, но столько раз, сколько выделенных объектов. Вот почему нам нужно установить активный объект из цикла.

примечание: я не очень знаком с блендером

Кажется, что bpy.ops операции зависят от состояния bpy.context, Контекст также может быть переопределен для каждой операции.

Я предполагаю что uv_texture_add() работает только на одном объекте одновременно?

Попробуйте что-то вроде этого:

import bpy

for x in bpy.context.selected_objects:
    override = { "selected_objects": x }
    bpy.ops.mesh.uv_texture_add(override)

Это должно запускать операции, как будто только один объект был выбран за один раз.

Источник:
https://www.blender.org/api/blender_python_api_2_63_17/bpy.ops.html

Другие вопросы по тегам