4
$\begingroup$

Trying to make a modelling tool that can update geometry in the 3D view as the user interacts with the scene. To do this the script needs to loop continuously so it can check for changes caused by the user. The problem seems to be that I cant get an infinite loop not to freeze Blender. I thought I could use something like...

import time

    def MainLoop():
        <code>

    While True:
        time.sleep(1)
        MainLoop()

However this freezes entirely and not sure why. Also if time.sleep() is used it not only stops the script but also Blender itself which defeats the purpose entirely.

This is meant to be a modelling tool and is not running through the BGE as it seems most talk about real time Blender scripts deal with BGE. As far as I can tell there is no built in time delta to use for non BGE scripts.

Update:

Made a threaded script in hopes that by running the process in a separate thread from the Blender GUI that time.sleep() could be called without affecting Blenders GUI but this did not work. After doing more reaserch on the threading module it worked! Can now make infinite loops limited with time.sleep() without pausing the Blender GUI in the process. Here is some example code...

import threading
import time

class ScriptThread (threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name


    def run(self):
        FPS = 1
        is_running = True

        tick = time.time()
        loop = 0
        while is_running is True:
            if time.time() >= tick+(1/FPS):
                tick = time.time()
                print(loop)
                time.sleep(1/FPS)
                loop += 1
                if loop >= 10:
                    is_running = False
            else:
                continue

#Make thread
thread = ScriptThread(1, "thread")
thread.start()

I'm not sure if this will have implications in querying and setting attributes in Blender but will find out soon enough.

$\endgroup$
5
  • $\begingroup$ You need a loop that starts with your script and stops with a key press. $\endgroup$
    – Yvain
    Apr 1, 2016 at 17:31
  • $\begingroup$ But how would that be different? It wouldn’t limit the execution speed of the script to prevent large CPU load. It only serves as a break. My concern is that In a game engine we have the benefit of a framework with time relative loops but outside of such a framework we do not. There must be a way to wait the script without stopping Blenders Python based GUI as well. $\endgroup$ Apr 1, 2016 at 17:48
  • $\begingroup$ I don't know the time function at all so I don't understand your code in the first place but why do you want to use a time function in a loop that you could close just by pressing enter or escape ? If you define your object 'mainloop' then put the loop inside of that object before making the call $\endgroup$
    – Yvain
    Apr 1, 2016 at 18:32
  • 1
    $\begingroup$ The code will have a break, yes. In this particular instance the break happens by pressing a button. But while the code is running it must not be allowed to run as fast as the CPU is capable of or else is simply ties up system resources needlessly. The time.sleep() function suspends the script for x number of seconds, in other words if you use time.sleep(1) you would suspend the script for one second before resuming operation. In theory you can use this suspend in a loop however I have found that this doesn’t work and that it also stops the Blender GUI as it is also Python based. $\endgroup$ Apr 1, 2016 at 18:46
  • 3
    $\begingroup$ You need to create a modal operator for this stuff; read this page on more information: blender.org/api/blender_python_api_2_76_2/… $\endgroup$
    – luke1985
    Apr 2, 2016 at 19:19

0

You must log in to answer this question.

Browse other questions tagged .