Ditch global lists and use selection
After calling the import operator any newly imported objects are selected and make up the context.selected_objects
list.
I don't have any multi-object stl files to test theory against, but will go thru the motions with a single object file.
With no current selection.
>>> C.selected_objects
[]
Import stl
>>> bpy.ops.import_mesh.stl(filepath="/home/batfinger/Desktop/untitled.stl")
Import finished in 0.0156 sec.
{'FINISHED'}
Newly imported object(s) (Have no examples of multi object stls)
>>> C.selected_objects
[bpy.data.objects['Untitled']]
Remove that import
>>> old_import = C.selected_objects
>>> while old_import:
... D.objects.remove(old_import.pop())
...
>>> C.selected_objects
[]
Import again
>>> bpy.ops.import_mesh.stl(filepath="/home/batfinger/Desktop/untitled.stl")
Import finished in 0.0140 sec.
{'FINISHED'}
>>> C.selected_objects
[bpy.data.objects['Untitled']]
Rename this time
>>> #and to rename
>>> for o in C.selected_objects:
... o.name = "Foo"
...
>>> C.selected_objects
[bpy.data.objects['Foo']]
What's the file looking like
>>> D.objects[:]
[bpy.data.objects['Camera'], bpy.data.objects['Foo'], bpy.data.objects['Lamp']]
Notes.
Basically think the remove method in question code is "icky", as also is keeping some global list with object references ... just asking for a crash.
Notice the way the objects were removed in python console code above. They are unlinked (de-usered) by default.
To use a list like so recommend only using names, or just not doing it that way.
Putting this into a script
Have made a version of the script using a custom property tag to "mark" any imported STL. And to keep the new, remove, rename order also looked at the name.. one thinks remove, new, rename makes more sense.. anyhow
import bpy
tag = 'IMPORTED_STL_OBJECT'
def new_stl(filepath):
# import a STL file
bpy.ops.import_mesh.stl(filepath=filepath)
# get new object list
# ops use context silly not to use it.
# could do set before / after here too.
for o in bpy.context.selected_objects:
o[tag] = 1
o.data[tag] = 1
def delete_old_stl(name="NewSTL"):
stls = [o for o in bpy.data.objects
if (name and o.name.startswith(name))
and tag in o.keys()]
while stls:
bpy.data.objects.remove(stls.pop())
stl_meshes = [m for m in bpy.data.meshes
if (name and m.name.startswith(name))
and tag in m.keys()]
while stl_meshes:
bpy.data.meshes.remove(stl_meshes.pop())
def rename_stl(name="NewSTL"):
stls = [o for o in bpy.data.objects
if tag in o.keys()]
for o in stls:
o.name = name
o.data.name = f"{name}_Mesh"
new_stl("/home/batfinger/Desktop/untitled.stl")
delete_old_stl()
rename_stl()
user_clear
line tryif jjj.users > 0
. Also I would replace the name of thejjj
variable byobj
, it's more clear. $\endgroup$ – Gorgious Feb 21 at 10:49