Comment trouver * efficacement * toutes les lumières d'une scène?
J'aimerais remplir une liste d'interface utilisateur personnalisée avec toutes les lumières de la scène actuelle, mais je ne suis pas sûr de la meilleure façon de le faire. Nous pourrions itérer bpy.context.scene.objectset valider object.type == 'LIGHT'pour filtrer les choses, puis utiliser objects[i].datapour obtenir la lumière réelle, mais cela me semble maladroit et non performant, en particulier pour les scènes contenant un grand nombre d'objets.
Idéalement, j'aimerais explorer bpy.data.lightset filtrer cet ensemble de données beaucoup plus petit en fonction de la ou des scènes dans lesquelles chaque lumière est utilisée. Mais, étant donné la lumière bpy.data.lights, comment puis-je trouver l'objet qui l'utilise et à partir de là vérifier l' user_sceneattribut de cet objet ? Cela me semble beaucoup plus rapide que d'itérer de haut en bas les attributs d'un bazillion d'objets data, mais s'il existe un mécanisme pour aller de bas en haut d'une lumière aux objets qui l'utilisent, je ne peux pas trouvez-le dans l'API. Des idées, des gens plus intelligents de StackExchange?
Merci beaucoup et excuses s'il s'agit d'un DOH! genre de question, je suis nouveau dans ce domaine et je me sens toujours dans le noir.
Réponses
Mettez-les dans une collection
OMI, le moyen le plus simple de le faire est, comme suggéré
scene_lights = [ob for ob in scene.objects if ob.type == 'LIGHT']
Un objet lumineux peut avoir les mêmes données lumineuses que tout ou partie des lumières d'une scène. Même s'il y a peu de lumières, vérifier que les données appartiennent à un objet de la scène peut s'avérer moins efficace que ci-dessus.
Si vous pensez qu'il y a tellement d'objets dans la scène que les itérer sur eux est inefficace, envisagez de les lier à une ou plusieurs collections à l'aide de la propriété name ou ID pour marquer la collection comme étant des objets légers.
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)
Pourrait créer des collections au sein de cette collection pour les catégoriser davantage par type de lumière
Pointeur interrogé
Comme mentionné par @brockmann, vous pouvez également envisager d'utiliser une propriété de pointeur interrogé, un exemple pour les matériaux
Données de recherche personnalisées vers UILayout.prop_search
alors que dans le cas des lumières, le type de propriété du pointeur serait bpy.types.Object, et la méthode d'interrogation serait testée par rapport au type. Pourrait facilement être étendu au type léger
utilisez le script ci-dessous:
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]