# Blender how to periodically reload file (python)

I'm trying to write script that will automatically reload file every few seconds. In order to do that I wrote following plugin:

bl_info = {"name": "[PonyKart] Auto scene update", "category": "Scene"}

import bpy

DELAY=30
timer=None

print("Updating")

def register():
print("Timer registered")
timer.start()

def unregister():
print("Timer cancelled")
timer.cancel()


But while it indeed does save file properly, it crashes Blender after doing so (I so i think it crashes when Blender opens file)

Just for reference here is code responsible for save_reload from amaranth plugin:

"""Save and Reload the current blend file"""

if not path:
bpy.ops.wm.save_as_mainfile("INVOKE_AREA")
return
bpy.ops.wm.save_mainfile()
bpy.ops.wm.open_mainfile("EXEC_DEFAULT", filepath=path)

def execute(self, context):
path = bpy.data.filepath
return {"FINISHED"}


I'm trying to allow online collaboration on single file. When person A works on file a.blend and person B on file b.blend and they cross-link each others grouped objects (lets say personA_group and personB_group) then with periodic file reaload users can get updated info on scene. Maybe it's not super realtime, but it works and uses relatively stable Blender mechanics.

I know there's verse and I know it doesn't work. Apart from spending like days trying to set it up after I managed to do it it crashes every few minutes and glitches as hell. It's so extremely unstable on hi-poly meshes that it's unusable. Also requires high bandwidth while method above (if we enable Blender file compression) requires only sending few MB file (usually around 1-2) over network every lets say 60 sec. It's possible to implement such mechanics using samba share. According to initial tests file reload over our samba share takes around 3-4 seconds using awfully slow connection so it's usable.

• hard to tell what's going wrong, possibly delay is too short, try if this happens with large delay. but could you add some information on why you do it?? – Noidea Oct 7 '16 at 16:32
• updated. 30 secons is quite big interval also I tried just manually creating thread from Blender console and the same happens - it crashes. Several methods behave weird when launched in separate thread - .quit_blender() also doesn't work. I tried to import bpy inside this callback method but it doesn't help either – Lapsio Oct 7 '16 at 17:08

Quote from the api documentation

Python threading with Blender only works properly when the threads finish up before the script does

There are two ways i know of to periodically run python code:

Register a handler for scene_update_post:

import bpy
import time

t = [0.0] * 3
t[0] = time.time()
handles = bpy.app.handlers.scene_update_post

@persistent
def on_scene_update(scene):
t[1] = time.time()
t[2]+= t[1] - t[0]
t[0] = t[1]
print("Time elapsed %f" % t[2])

if t[2] > 20.0:
handles.remove(on_scene_update)

handles.append(on_scene_update)


Use a modal operator (in this case the code only runs when the user interacts with blender):

import bpy
import time

class OT_INFO_time_elapsed(bpy.types.Operator):
bl_idname = "info.time_elapsed"
bl_label = "Print elapsed time to the console"
bl_options = set()

def invoke(self, context, event):
self.current = time.time()
self.prev = self.current
self.elapsed = 0.0
return {'RUNNING_MODAL'}

def modal(self, context, event):
self.current = time.time()
self.elapsed += self.current - self.prev
self.prev = self.current
print("Time elapsed: %f" % self.elapsed)
return {'PASS_THROUGH'}

def register():
bpy.utils.register_class(OT_INFO_time_elapsed)

def unregister():
bpy.utils.unregister_class(OT_INFO_time_elapsed)

if __name__ == "__main__":
register()


Since you intend to reload the file only the handler using the @persistent decorator will work.

• so if i'd like to use first variant - I should put save_reload() after handles.remove(...) right? then it'll reload file after user updates scene AND required time elapsed? – Lapsio Oct 7 '16 at 18:13
• I'm getting persistent is not defined – Lapsio Oct 7 '16 at 18:15
• after importing @persistent this first variant also crashes blender. Exactly in the same way as thread. But modal operator does not and works properly so I think I have to use this method. – Lapsio Oct 7 '16 at 18:28