Jak * skutecznie * znaleźć wszystkie światła w scenie?

Nov 26 2020

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.objectsi zweryfikować, object.type == 'LIGHT'aby odfiltrować rzeczy, a następnie użyć ich objects[i].datado 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.lightsa 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_sceneatrybut tego obiektu ? Wydaje mi się, że jest to znacznie szybsze niż iterowanie z góry na dół po dataatrybutach 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

2 batFINGER Nov 27 2020 at 11:28

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

MohammadHosseinJamshidi Nov 27 2020 at 04:20

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]