Как добавить модификатор зеркала ко всем объектам определенной коллекции?
Я бы хотел добавить модификатор зеркала к каждому объекту определенной коллекции.
Проблема в том, что модификатор будет добавлен только к последнему объекту, который даже получит один и тот же модификатор несколько раз, и я не знаю почему:
def add_empty_collection(self):
for obj in bpy.data.collections['my_collection'].all_objects:
print("obj_: ", obj)
bpy.ops.object.select_all(action='DESELECT') # Deselecting all
obj.select_set(True)
bpy.ops.object.modifier_add(type='MIRROR')
bpy.context.object.modifiers["Mirror"].use_axis[0] = False
bpy.context.object.modifiers["Mirror"].use_axis[1] = True
bpy.context.object.modifiers["Mirror"].use_axis[2] = False
bpy.context.object.modifiers["Mirror"].mirror_object = bpy.data.objects["target"]
В: Как добавить модификатор зеркала ко всем объектам определенной коллекции?
Ответы
Лучше использовать, bpy.data.objectsчтобы ими манипулировать. Таким образом, вам не нужно полагаться на то, что выбрано, все, что вам нужно, это имя объекта.
import bpy
mod_name = 'My-Mirror-Modifier'
for obj in bpy.data.collections["My-Collection"].all_objects:
if obj.type == 'MESH':
mod = obj.modifiers.new(mod_name, 'MIRROR')
mod.use_axis[0] = False
mod.use_axis[1] = True
mod.use_axis[2] = False
mod.mirror_object = bpy.data.objects["Light"]
Для операторов используйте context.
Учитывая selfкод в вопросе, предполагая, что вы пишете оператор
В дополнение к ответу @RoufirHassan в качестве объяснения, цикл по объектам коллекции, отменяющий выбор и выбор одного, не изменял активный объект. Добавление context.objectв выписку для печати подтвердит это.
Всегда ли активный объект и нулевой выбранный объект одинаковы?
чтобы исправить, установите активный объект в объект цикла перед вызовом оператора.
context.view_layer.objects.active = obj
Blender 2.8 API, python, установить активный объект
Однако проблема здесь в том, что скрипты имеют тенденцию к ужасному замедлению, если в цикле выполняется большое количество операторов. Счетчик запусков оператора с использованием измененного кода вопроса будет равен 2-кратному количеству объектов в коллекции.
Оператор добавления модификатора добавляет в конец стека модификаторов
при использовании оператора добавления модификаторов вновь добавленный модификатор будет
context.object.modifiers[-1]
т.е. последний. Еще раз, в блендере использование имени может быть изворотливым, точно так же, как с объектами, добавляющими другое с тем же именем, не будет иметь того же имени.
Главный кандидат на KeyError
Никогда не используйте, bpy.data.whatevers["Foo"]если вы не уверены, что "Foo" существует. Где он может иметь значение. NoneТакже рекомендуется использовать объекты сцены, так как если объект bpy.data.objectsне связан со сценой, он, скорее всего, не будет работать должным образом.
target = context.scene.objects.get("Foo")
или используйте контекст. В этом случае, например, коллекция может быть контекстной коллекцией (последней выбранной в планировщике), а цель модификатора может бытьcontext.object
Превалирующий контекст
Может передавать операторам контекстный словарь. Ниже приведен метод, объясненный @RoufirHassan с использованием переопределения. Примечание: это добавит все модификаторы первого объекта сетки в коллекции (включая недавно добавленное зеркало) ко всем другим объектам сетки в коллекции, за исключением цели зеркала, если это объект сетки в той же коллекции
При этом будут выполняться только 2 оператора, независимо от того, сколько объектов в коллекции.
import bpy
context = bpy.context
coll = context.collection
ob = context.object
mesh_obs = [o for o in coll.all_objects
if o.type == 'MESH'
and o is not ob]
if mesh_obs:
ao = mesh_obs.pop(0)
bpy.ops.object.modifier_add(
{"object" : ao},
type='MIRROR'
)
mod = ao.modifiers[-1]
mod.use_axis = (True, False, True)
mod.mirror_object = ob
bpy.ops.object.make_links_data(
{"object" : ao,
"selected_editable_objects": mesh_obs
},
type='MODIFIERS',
)
Методы API.
Наконец, я бы рекомендовал использовать метод API, как предложено в ответе @Pysonic , за исключением использования контекста для установки целевого объекта коллекции и модификатора.
Выделите все меши в своей коллекции и добавьте модификатор зеркала.
Но, как вы сказали, он будет отражать только активный объект (активный объект = последний объект, выбранный с другим цветным контуром). Поэтому, чтобы отразить каждый объект, просто введите ( Ctrl+ L) > модификаторы . Он свяжет все объекты с одним и тем же модификатором.
Вы можете использовать его для любых других модификаторов.