Is there a way to select all cameras without iterating through every object in a scene?

Hi! I got my first job in a studio as a junior pipeline TD (but I don’t have much experience in this field, I applied as an asset artist ;p)

Buuut, to the point. I need a way to select certain cameras in a scene. My plan is to get all camera objects in a scene, and then based on their names get the ones that I need.

Currently I’m selecting all cameras like this:
all_cams = [ob for ob in list(bpy.context.scene.objects) if ob.type == ‘CAMERA’]

But i think there should be a better way to do this, without iterating through all objects in a scene.
We got D.cameras class and from there I can get all data-block names. But how I can go from data-block names to the object name?

Or at least how do I select the cameras using their data-block name? ( then I can work further based on selected objects)

Do you got any ideas how can i achieve what I want? Thank you!

Here’s one potential solution:

camera_names = [cam.name for cam in bpy.data.cameras]

camera_objects = [bpy.context.scene.objects[name] for name in camera_names]

selected_cameras = [camera for camera in camera_objects if camera.select_get()]

Generally, there are better forums for such questions though. This place is for developing Blender itself, mostly. The #python channel on https://blender.chat/ or https://blender.stackexchange.com/ are good resources for these types of questions.

Thank you for reply. Solution you mentioned does not work ( in first line you are getting data-block name, and in 2nd line you want to refer to objects using data-block names ( and you can’t do it))

I will move discussion to the sites you mentioned, sorry ;p

Works fine here in the script editor

>>> camera_names = [cam.name for cam in bpy.data.cameras]
>>> camera_objects = [bpy.context.scene.objects[name] for name in camera_names]
>>> selected_cameras = [camera for camera in camera_objects if camera.select_get()]
>>> selected_cameras
[bpy.data.objects['Camera']]

It works only if you Camera object name is equal to data-block name ;p

Ah, yes. Sorry for leading you astray there, didn’t read closely.

Not sure if you found your answer, but you should be able to use the user_map call to get the objects that have the data-block in question. For instance:

for c in bpy.data.cameras:
    user_map = bpy.data.user_map(subset={c}, value_types={'OBJECT'})
    for cam_obj in user_map[c]:
        # do something with cam_obj

Thank you! It does exactly what I want ^^ Didn’t know about this function. ( I was looking in D.cameras)

I’m pretty sure this will also internally loop over all objects in the file, even worse since it uses a lookup by data :slight_smile:

Quick test with ~5k objects and 1300 cameras :

for c in bpy.data.cameras:
     user_map = bpy.data.user_map(subset={c}, value_types={'OBJECT'})
     for cam_obj in user_map[c]:
         cam_obj.select_set(True)

takes 0.915 seconds

and

[obj.select_set(True) for obj in bpy.data.objects if obj.type == "CAMERA"]

takes 0.003 seconds (300 times faster)

Code is here for information https://github.com/blender/blender/blob/master/source/blender/python/intern/bpy_rna_id_collection.c

Ah, didn’t know user_map was doing that behind the scenes. Good to know! I’m currently using it to figure out what is using a specific ShaderNodeTree.