2
$\begingroup$

I a writing a small script that periodically reloads an stl file into the scene, every X seconds. I managed to reload the stl object in my scene with the current script:

import bpy

@bpy.app.handlers.persistent
def Reload():
    for o in bpy.context.scene.objects:
        if o.type == "MESH":
            o.select_set(True)
        else:
            o.select_set(False)

    bpy.ops.object.delete()
    
    for mesh in bpy.data.meshes:
        bpy.data.meshes.remove(mesh)

    bpy.ops.import_mesh.stl(filepath="XXX\Test.stl")
    return 2

bpy.app.timers.register(Reload)
    

However, by doing this if i have another object selected when the "reload" function is fired, i loose the selection, which is very annoying.

How could i "save" the selection and restore it after reloading the STL file?

$\endgroup$
1
  • $\begingroup$ Why do you select all meshes and delete them before reloading the stl? How do you expect to reselect anything after reload? And another nitpick: you can simply write o.select_set(o.type == "MESH"). $\endgroup$
    – taiyo
    Dec 8, 2023 at 14:44

2 Answers 2

3
$\begingroup$

Save the selected objects to a list and then just select them again:

import bpy

selection = bpy.context.selected_objects

# something that changes the selection goes here

#deselect all in case something not needed is selected
bpy.ops.object.select_all(action='DESELECT') 
# for every saved object set it to be selected
for o in selection:
    o.select_set(True)

If you replace the objects selected by something you load again, you need to find some property that does not change after reimporting. Maybe object name?

Then:

import bpy

selection = [o.name for o in bpy.context.selected_objects]

bpy.ops.object.select_all(action='DESELECT')
for name in selection:
    bpy.context.scene.objects[name].select_set(True)

Maybe the name gets changed during import because it exists already, so .001, .002 .. is added to it. You would have to deal with that.

$\endgroup$
2
  • $\begingroup$ OK (i saw your edit just when i was posting) In my case as i'm doing something very specific i made sure that the name would not change so it's enough, ans it works. the script was stopping on error as i was trying to select an object that no longer existed. $\endgroup$
    – J.M
    Dec 8, 2023 at 14:48
  • $\begingroup$ What crashes exactly? $\endgroup$ Dec 8, 2023 at 14:50
0
$\begingroup$

IMO classic XY problem, it's solved with a one-liner and batch_remove : bpy.data.batch_remove([o for o in bpy.data.objects if o.type == "MESH"] + list(bpy.data.meshes)), no need to mess with selection state.

$\endgroup$
4
  • 1
    $\begingroup$ Also you should never iterate over a list while you delete some of its elements rather use for mesh in bpy.data.meshes[:]: bpy.data.meshes.remove(mesh) $\endgroup$
    – Gorgious
    Dec 8, 2023 at 15:38
  • $\begingroup$ If I understand it correctly, they have something selected and want to reload and replace objects and the selection to match what it was. How does this deal with selecting replaced objects? What am I missing? $\endgroup$ Dec 8, 2023 at 15:54
  • $\begingroup$ @MartynasŽiemys as I said in the answer I think this is a XY problem, sure you can store a selection state and restore it later, but if you don't have to mess with it in the first place why bother ? $\endgroup$
    – Gorgious
    Dec 9, 2023 at 13:45
  • $\begingroup$ I think stl importer deselects stuff and selects whatever is imported. Can it import mesh data only without creating objects? $\endgroup$ Dec 9, 2023 at 16:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .