Петля не работает, трехстрочный код 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