Como encontrar * eficientemente * todas as luzes em uma cena?
Gostaria de preencher uma lista de IU personalizada com todas as luzes que estão na cena atual, mas não tenho certeza da melhor maneira de fazer isso. Poderíamos iterar bpy.context.scene.objects
e validar object.type == 'LIGHT'
para filtrar as coisas e então usar objects[i].data
para obter a luz real, mas isso me parece desajeitado e sem desempenho, especialmente para cenas que têm um grande número de objetos.
Idealmente, gostaria de detalhar bpy.data.lights
e filtrar esse conjunto de dados muito menor com base na (s) cena (s) em que cada luz é usada. Mas, dada uma luz bpy.data.lights
, como posso encontrar o objeto que está usando, e a partir daí verificar o user_scene
atributo desse objeto ? Isso me parece ser muito mais rápido do que iterar de cima para baixo sobre os data
atributos de um zilhão de objetos , mas se houver um mecanismo para ir de baixo para cima a partir de uma luz para o (s) objeto (s) que a está usando, então não posso encontre-o na API. Alguma ideia, pessoal mais inteligente do StackExchange?
Muito obrigado e desculpas se este é um DOH! tipo de pergunta, eu sou novo nisso e ainda estou tateando no escuro.
Respostas
Coloque-os em uma coleção
IMO a maneira mais simples de fazer isso é, conforme sugerido
scene_lights = [ob for ob in scene.objects if ob.type == 'LIGHT']
Um objeto de luz pode ter os mesmos dados de luz que qualquer uma ou todas as luzes em uma cena. Mesmo se houver poucas luzes, verificar se os dados pertencem a um objeto na cena pode ser menos eficiente do que acima.
Se você sentir que há tantos objetos na cena que iterar sobre eles é ineficiente, considere vinculá-los a uma (s) coleção (ões) usando a propriedade de nome ou ID para marcar a coleção como sendo de objetos leves.
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)
Pode fazer coleções dentro desta coleção para categorizar ainda mais por tipo de luz
Polled PointerProperty
Como mencionado por @brockmann também pode considerar o uso de uma propriedade de ponteiro sondado, um exemplo para materiais
Dados de pesquisa personalizados para UILayout.prop_search
ao passo que, no caso de luzes, o tipo de propriedade de ponteiro seria bpy.types.Object
, e o método de votação seria testado em relação ao tipo. Pode ser facilmente estendido para o tipo de luz
use o script abaixo:
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]