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
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.