It should be worth noting that using operators often forces a whole scene reload.
If you can write the equivalent code with low-level access, you can bypass those updates and do one update in the end.
Basically, you would have to rewrite the code of each operator using “normal” data access. This will inevitably involve writing much more code, but could be worth the effort if you need to do such a task often.
True. Though there’s some low hanging fruit to harvest first.
The code as-written operates on each object regardless of whether they are even meshes at all.
It also operates on every instance of each block of mesh data, so if you have lots of duplicates (meshes that share the same data) it will waste a bunch of time cleaning the same data over and over.
And finally, the failure to remove some doubles is because the “remove doubles” operation only operates on selected vertices. So we need to select all vertices first.
My version, incorporating these changes, is as follows:
checked = set()
selected_objects = bpy.context.selected_objects
for selected_object in selected_objects:
if selected_object.type != 'MESH':
meshdata = selected_object.data
if meshdata in checked:
bpy.context.scene.objects.active = selected_object
If this still runs too slowly for you, consider -HENDRIX- suggestion to re-bind the ops calls. The “remove_doubles” is probably the main culprit, as it prints to the console, which takes forever.