Comment ajouter un modificateur de miroir à tous les objets d'une certaine collection?
Je voudrais ajouter un modificateur de miroir à chaque objet d'une certaine collection.
Le problème est que le modificateur ne sera ajouté qu'au dernier objet qui reçoit même le même modificateur plusieurs fois et je ne sais pas pourquoi:
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"]
Q: Comment ajouter un modificateur de miroir à tous les objets d'une certaine collection?
Réponses
Vous feriez mieux bpy.data.objects
de les manipuler. De cette façon, vous n'avez pas besoin de vous fier à ce qui est sélectionné, tout ce dont vous avez besoin est le nom des objets.
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"]
Pour les opérateurs, utilisez le contexte.
Étant donné le self
code de la question, en supposant que vous écrivez un opérateur
Suite à la réponse de @RoufirHassan en guise d'explication, faire une boucle sur les objets de la collection, désélectionner et sélectionner un seul, ne changeait pas l'objet actif. L'ajout context.object
d'une déclaration imprimée le confirmerait.
L'objet actif et l'objet sélectionné à zéro sont-ils toujours les mêmes?
pour corriger, définissez l'objet actif sur l'objet de boucle avant d'appeler l'opérateur.
context.view_layer.objects.active = obj
API Blender 2.8, python, définir un objet actif
Cependant, un problème ici serait que les scripts ont tendance à ralentir horriblement s'ils bouclent beaucoup d'opérateurs. Le nombre d'exécutions de l'opérateur utilisant le code de question modifié serait de 2 x le nombre d'objets dans la collection.
L'opérateur d'ajout de modificateur ajoute à la fin de la pile de modificateurs
si vous utilisez l'opérateur d'ajout de modificateurs, le modificateur nouvellement ajouté sera
context.object.modifiers[-1]
c'est-à - dire le dernier. Encore une fois dans Blender, utiliser le nom peut être douteux, tout comme avec des objets, ajouter un autre avec le même nom n'aura pas le même nom.
Premier candidat pour KeyError
Ne jamais utiliser bpy.data.whatevers["Foo"]
sauf si vous êtes certain que "Foo" existe. Où il peut avoir de la valeur None
Recommandez également d'utiliser des objets de scène, comme si l'objet dans bpy.data.objects
n'est pas lié à la scène, il ne fonctionnera probablement pas comme prévu.
target = context.scene.objects.get("Foo")
ou utilisez le contexte. Dans ce cas par exemple, la collection peut être une collection de contexte (dernière sélection dans outliner) et la cible du modificateur peut êtrecontext.object
Contexte de remplacement
Peut transmettre un dictionnaire de contexte aux opérateurs. Ci-dessous, la méthode expliquée par @RoufirHassan utilisant le remplacement. Remarque: cela ajoutera tous les modificateurs du premier objet de maillage de la collection (y compris le miroir nouvellement ajouté) à tous les autres objets de maillage de la collection, sauf à la cible du miroir s'il s'agit d'un objet de maillage de la même collection
Cela n'exécutera que 2 opérateurs, quel que soit le nombre d'objets dans la collection.
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éthodes API.
Enfin, je recommanderais d'utiliser la méthode API comme suggéré dans la réponse de @Pysonic , sauf d'utiliser le contexte pour définir la cible de la collection et du modificateur.
Sélectionnez tous les maillages de votre collection et ajoutez un modificateur de miroir.
Mais comme vous l'avez dit, il ne reflétera que l'objet actif (objet actif = dernier objet sélectionné avec un contour de couleur différente). Donc, pour refléter chaque objet, tapez simplement ( Ctrl+ L) > modifiers . Il liera tous les objets avec le même modificateur.
Vous pouvez l'utiliser pour tous les autres modificateurs.