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
    return lights_list

l = get_lights()

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

>>> 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
# lights in blend
# lights in active collection
| improve this answer | |

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.