I am trying to make a script that works kind of the same as Merge by Distance but to be used in Object mode. Basically, what I am trying to do is join all the objects that have their origin at the same location. This is the script I tried to use :
import bpy;
visible_objects=[ob for ob in bpy.context.view_layer.objects if ob.visible_get()];
#get all the visible objects in a list
for o in visible_objects: #iterate the objects
bpy.context.view_layer.objects.active= o; #set the current one as active
for j in visible_objects: #iterate again
if j== o:
continue;
if j.location== o.location: #join the objects sharing location with the current one
j.select_set(True);
bpy.ops.object.join();
There are 2 problems with this code.
The first one is a logical one, once an object is joined to another, it "disappears" but the visible_objects list is still referencing it so I get the obvious error : "ReferenceError: StructRNA of type Object has been removed".
The second problem is that I keep receiving the warning "Warning: Active object is not a selected mesh" after each join even though I already set an object as active with bpy.context.view_layer.objects.active= o and all the other objects are meshes.
Is there a way to get rid of the warning and how do I fix the algorithm so that the inexistant objects are not anymore referenced by the list?
rev_multidict.setdefault(v, set()).add(k). I know it addsktorev_multidictbut I don't understrand whatsetdefault(v, set())does. – mqbaka mqbaka Sep 21 '22 at 10:28defaultdictinstead,setdefaultreads a value from a dictionary. If no value is found, it sets the value to the - in this case -set(), then it reads the value again, so now it has either a reference to the new set just created, or a reference to a set that was already there. – Markus von Broady Sep 21 '22 at 10:30to_tuple- I don't know if it's faster, but should be otherwise there's no reason for it to be there – Markus von Broady Sep 21 '22 at 10:32from collections import defaultdict; dic = defaultdict(set); for obj in bpy.data.objects: dic[obj.location.to_tuple()].add(obj)thenfor objects in dic.values(): ...– Gorgious Sep 21 '22 at 11:50