Jak dodać modyfikator lustra do wszystkich obiektów w określonej kolekcji?
Chciałbym dodać modyfikator lustra do każdego obiektu z określonej kolekcji.
Problem w tym, że modyfikator zostanie dodany tylko do ostatniego obiektu, który nawet kilka razy dostaje ten sam modyfikator i nie wiem dlaczego:
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: Jak dodać modyfikator lustra do wszystkich obiektów w określonej kolekcji?
Odpowiedzi
Lepiej jest użyć ich bpy.data.objects
do manipulowania nimi. W ten sposób nie musisz polegać na tym, co jest zaznaczone, wystarczy tylko nazwa obiektu.
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"]
Dla operatorów użyj kontekstu.
Biorąc pod uwagę self
w kodzie pytania, zakładając, że piszesz operator
W nawiązaniu do odpowiedzi @RoufirHassan w celu wyjaśnienia, zapętlanie się po obiektach kolekcji odznaczanie i wybieranie pojedynczych, nie zmieniało aktywnego obiektu. Dodanie context.object
do wydruku oświadczenia mogłoby to potwierdzić.
Czy obiekt aktywny i obiekt zaznaczony jako zerowy zawsze są takie same?
naprawić ustaw obiekt aktywny na obiekt pętli przed wywołaniem operatora.
context.view_layer.objects.active = obj
Blender 2.8 API, python, ustaw aktywny obiekt
Jednak problemem byłoby to, że skrypty mają tendencję do strasznego zwalniania, jeśli zapętlają wiele operatorów. Liczba uruchomień operatora przy użyciu zmienionego kodu pytania wyniosłaby 2 x liczba obiektów w kolekcji.
Operator add modyfikatora dodaje na koniec stosu modyfikatorów
jeśli używasz modyfikatorów add operator, to nowo dodany modyfikator będzie
context.object.modifiers[-1]
czyli ostatni. Ponownie w blenderze użycie nazwy może być podejrzane, tak jak w przypadku obiektów o tej samej nazwie nie będzie miało tej samej nazwy.
Główny kandydat na KeyError
Nigdy nie używaj, bpy.data.whatevers["Foo"]
jeśli nie masz pewności, że istnieje „Foo”. Gdzie może to mieć wartość None
Zalecamy również używanie obiektów sceny, tak jakby obiekt bpy.data.objects
nie był powiązany ze sceną, prawdopodobnie nie będzie działał zgodnie z oczekiwaniami.
target = context.scene.objects.get("Foo")
lub użyj kontekstu. W tym przypadku na przykład kolekcja może być kolekcją kontekstową (ostatnio wybraną w programie outliner), a celem modyfikatora może byćcontext.object
Nadrzędny kontekst
Może przekazywać słownik kontekstowy do operatorów. Poniżej znajduje się wyjaśnienie metody @RoufirHassan za pomocą zastąpienia. Uwaga: spowoduje to dodanie wszystkich modyfikatorów pierwszego obiektu siatki w kolekcji (w tym nowo dodanego lustra) do wszystkich innych obiektów siatki w kolekcji, z wyjątkiem celu odbicia lustrzanego, jeśli jest to obiekt siatkowy w tej samej kolekcji
Spowoduje to uruchomienie tylko 2 operatorów, niezależnie od liczby obiektów w kolekcji.
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',
)
Metody API.
Na koniec poleciłbym użycie metody API, jak zasugerowano w odpowiedzi @Pysonic , z wyjątkiem używania kontekstu do ustawiania celu kolekcji i modyfikatora.
Wybierz wszystkie siatki w swojej kolekcji i dodaj modyfikator lustra.
Ale jak powiedziałeś, będzie to odzwierciedlać tylko aktywny obiekt (aktywny obiekt = ostatni wybrany obiekt z innym kolorowym konturem). Aby więc odzwierciedlić każdy obiekt, wystarczy wpisać ( Ctrl+ L) > modyfikatory . Połączy wszystkie obiekty z tym samym modyfikatorem.
Możesz go użyć do dowolnych innych modyfikatorów.