2
$\begingroup$

I am trying to collect information about lights existing in the scene with python. For now I have color, strength, type and so on but now I need to store also location and rotation of the instances. How should I approach it?

For now this is how it looks like:

import bpy
import math


def get_lights():
    
    lights_list = []
    
    for light in bpy.data.lights:
        
        light_dict = {}
        
        light_dict['type'] = light.type
        
        light_dict['name'] = light.name
        
        if light.type == 'SPOT':
            light_dict['angle'] = int(light.spot_size*180/math.pi)
        

        if light.type == 'SPOT' or light.type == 'POINT':
            light_dict['size'] = light.shadow_soft_size
            
        light_dict['strength'] = light.energy
        
        light_color = []
        light_color.append(round(light.color.r, 2))
        light_color.append(round(light.color.g, 2))
        light_color.append(round(light.color.b, 2))
        light_dict['color'] = light_color
        
        
        lights_list.append(light_dict)
        
    return lights_list

l = get_lights()
print(l)
``` 
$\endgroup$
1
$\begingroup$

For global locations use matrix world

To make sure the global transform of light is as shown visually recommend using the matrix world. Eg for default lamp global location and rotation

All the global transform info is available in the matrix.

>>> C.object
bpy.data.objects['Lamp']

>>> C.object.matrix_world
Matrix(((-0.29086464643478394, -0.7711008191108704, 0.5663931965827942, 4.076245307922363),
        (0.9551711678504944, -0.1998833566904068, 0.21839119493961334, 1.0054539442062378),
        (-0.05518905818462372, 0.6045247316360474, 0.7946722507476807, 5.903861999511719),
        (0.0, 0.0, 0.0, 1.0)))

>>> C.object.matrix_world.to_translation() # global location
Vector((4.076245307922363, 1.0054539442062378, 5.903861999511719))

>>> C.object.matrix_world.to_euler() # global rot in Eulers
Euler((0.6503280401229858, 0.055217113345861435, 1.8663908243179321), 'XYZ')

Remember all angles are in radians.

By using ob.matrix_world.copy() in code below it creates a "snapshot" of when script was run. If ob.matrix_world is used it is bound to the reference of the light and will change when transformed, an most likely crash blender if referenced after object is removed.

import bpy

def get_lights(col):
    assert(hasattr(col, "objects"))
    def to_dict(light):
        d = {}
        # add stuff already got
        d["matrix_world"] = light.matrix_world.copy()        
        return d

    return [to_dict(o) for o in col.objects if o.type == 'LIGHT']

# test call
# lights in scene
print(get_lights(bpy.context.scene))
# lights in blend
print(get_lights(bpy.data))
# lights in active collection
print(get_lights(bpy.context.collection))
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.