¿Cómo agregar un modificador de espejo a todos los objetos de una determinada colección?
Me gustaría agregar un modificador de espejo a cada objeto de una colección determinada.
El problema es que el modificador solo se agregará al último objeto que incluso obtiene el mismo modificador varias veces y no sé por qué:
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"]
P: ¿Cómo agregar un modificador de espejo a todos los objetos de una colección determinada?
Respuestas
Es mejor usarlos bpy.data.objects
para manipularlos. De esta manera, no necesita depender de lo que está seleccionado, todo lo que necesita es el nombre de los objetos.
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"]
Para los operadores, use el contexto.
Dado el self
en el código de la pregunta, suponiendo que está escribiendo un operador
Además de la respuesta de @RoufirHassan a modo de explicación, recorrer los objetos de colección deseleccionando y seleccionando solo, no estaba cambiando el objeto activo. Agregar context.object
a la declaración impresa confirmaría esto.
¿El objeto activo y el objeto seleccionado cero son siempre iguales?
para arreglar, establezca el objeto activo en el objeto de bucle antes de llamar al operador.
context.view_layer.objects.active = obj
Blender 2.8 API, python, establecer objeto activo
Sin embargo, un problema aquí sería que los scripts tienen una tendencia a ralentizarse horriblemente si se repiten muchos operadores. El recuento de ejecuciones del operador utilizando el código de pregunta modificado sería 2 x número de objetos en la colección.
El operador de adición de modificador se agrega al final de la pila de modificadores
si usa el operador de adición de modificadores, el modificador recién agregado será
context.object.modifiers[-1]
es decir, el último. Una vez más, en Blender, usar el nombre puede ser complicado, al igual que con los objetos, agregar otro con el mismo nombre no tendrá el mismo nombre.
Candidato principal para KeyError
Nunca lo use a bpy.data.whatevers["Foo"]
menos que esté seguro de que "Foo" existe. Dónde puede tener valor None
También recomiende el uso de objetos de escena, ya que si el objeto en bpy.data.objects
no está vinculado a la escena, probablemente no funcionará como se esperaba.
target = context.scene.objects.get("Foo")
o usa el contexto. En este caso, por ejemplo, la colección puede ser una colección de contexto (la última seleccionada en el esquema) y el objetivo del modificador puede sercontext.object
Contexto primordial
Puede pasar un diccionario de contexto a los operadores. A continuación se muestra el método explicado por @RoufirHassan mediante la anulación. Nota: esto agregará todos los modificadores del primer objeto de malla en la colección (incluido el espejo recién agregado) a todos los demás objetos de malla en la colección, excepto al objetivo del espejo si es un objeto de malla en la misma colección
Esto ejecutará solo 2 operadores sin importar cuántos objetos haya en la colección.
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',
)
Métodos API.
Finalmente, recomendaría usar el método API como se sugiere en la respuesta de @Pysonic , excepto que use el contexto para establecer la colección y el objetivo del modificador.
Seleccione todas las mallas de su colección y agregue un modificador de espejo.
Pero como dijiste, solo reflejará el objeto activo (objeto activo = último objeto seleccionado con un contorno de color diferente). Entonces, para reflejar cada objeto, simplemente escriba ( Ctrl+ L) > modificadores . Vinculará todos los objetos con el mismo modificador.
Puede usarlo para otros modificadores.