Jak * skutecznie * znaleźć wszystkie światła w scenie?
Chciałbym wypełnić listę niestandardowego interfejsu użytkownika wszystkimi światłami, które są w bieżącej scenie, ale nie jestem pewien, jak to zrobić. Moglibyśmy powtórzyć bpy.context.scene.objects
i zweryfikować, object.type == 'LIGHT'
aby odfiltrować rzeczy, a następnie użyć ich objects[i].data
do uzyskania rzeczywistego światła, ale wydaje mi się to niezgrabne i niedziałające, szczególnie w przypadku scen, które mają dużą liczbę obiektów.
Idealnie chciałbym zagłębić się, bpy.data.lights
a następnie przefiltrować ten znacznie mniejszy zestaw danych w oparciu o scenę (sceny), w których jest używane każde światło. Ale biorąc pod uwagę światło w bpy.data.lights
, jak mogę znaleźć obiekt, który go używa, a następnie sprawdzić user_scene
atrybut tego obiektu ? Wydaje mi się, że jest to znacznie szybsze niż iterowanie z góry na dół po data
atrybutach obiektów , ale jeśli istnieje mechanizm oddolnego przechodzenia od światła do obiektów, które go używają, to nie mogę znajdź go w API. Jakieś pomysły, mądrzejsi ludzie ze StackExchange?
Wielkie dzięki i przeprosiny, jeśli jest to DOH! rodzaj pytania, jestem nowy w tym i nadal poruszam się po ciemku.
Odpowiedzi
Umieść je w kolekcji
IMO najprostszym sposobem na to jest, zgodnie z sugestią
scene_lights = [ob for ob in scene.objects if ob.type == 'LIGHT']
Jeden jasny obiekt może mieć te same dane dotyczące światła, co dowolne lub wszystkie światła w scenie. Nawet jeśli jest niewiele świateł, sprawdzenie, czy dane należą do obiektu na scenie, może okazać się mniej wydajne niż powyżej.
Jeśli uważasz, że w scenie jest tak wiele obiektów, że iterowanie po nich jest nieefektywne, rozważ połączenie ich z kolekcją (kolekcjami) za pomocą nazwy lub właściwości ID w celu oznaczenia kolekcji jako obiektów lekkich.
lightcol = bpy.data.collections.get("Lights")
if not lightcol:
lightcol = bpy.data.collections.new("Lights")
scene.collection.children.link(lightcol) # or wherever
# populate it.
for lt in scene_lights:
lightcol.objects.link(lt)
Może spowodować, że kolekcje w tej kolekcji będą dalej kategoryzowane według typu światła
Polled PointerProperty
Jak wspomniał @brockmann, można również rozważyć użycie właściwości wskaźnika odpytywanego, na przykład dla materiałów
Dane wyszukiwania niestandardowego do UILayout.prop_search
podczas gdy w przypadku świateł typ właściwości wskaźnika byłby taki bpy.types.Object
, a metoda poll testowałaby typ. Można go łatwo rozszerzyć do typu lekkiego
użyj poniższego skryptu:
import bpy
light_set = set(bpy.data.lights.keys())
obj_set = set(bpy.data.objects.keys())
# light data doesn't update by deleting:
light_set.intersection_update(obj_set)
light_objects = [bpy.data.objects[name] for name in light_set]