Drawbot Multiprocessing
-
Hey all,
Some time ago I got frustrated by the render time so I played a little with multiprocessing. I switched from Drawbot to Processing I wanted to share this code with you guys. Just came across it and figured to share.
Now, don't ask me what does what, since I don't remember
:)
But I'm sure this will help some people with some long renders. You can render multiple frames a once, so no multiprocessing on one frame.# main.py import threading from queue import Queue import multiprocessing import datetime import time import drawBot # import settings as set def run(args): frame = args#[0] print("frame: ", frame) drawBot.newDrawing() # start from scratch, no multipage drawBot.newPage(set.canvasWidth, set.canvasHeight) time = frame / set.frames # teken een achtergrond drawBot.fill(1) # wit drawBot.rect(0, 0, set.canvasWidth, set.canvasHeight) drawBot.fill(0) # zwart angle = drawBot.radians(360 * time) x = set.canvasWidth / 2 + 100 * drawBot.sin(angle) drawBot.oval(x - 100, 200, 200, 200) drawBot.saveImage(set.pathExport + set.exportFileName + str(frame) + "." + set.exportFileType) for i in range(20): frame = frame * frame def threader(): while True: worker = q.get() run([ worker ]) q.task_done() q = Queue() def main_tr(): for x in range(10): t = threading.Thread(target=threader) t.daemon = True t.start() start = time.time() for worker in range(100): q.put(worker) q.join() print('total time', time.time() - start) def main_pool(): multiprocessing.set_start_method('spawn') p = multiprocessing.Pool( processes = (multiprocessing.cpu_count()-1)) p.map(run, range(set.frames)) p.close def main_mp(): processes = multiprocessing.cpu_count() print( 'utilizing %d cores\n' % processes ) ctx = multiprocessing.get_context('spawn') processes = [] queue = ctx.Queue() # what does this do? :) :) for frame in range(set.frames): processes.append(ctx.Process(target=run, args=([ frame ], ))) for p in processes: p.start() for p in processes: p.join() # for _ in range(times): # I've commented this one out. It works without. But what does it do? :) :) # assert queue.get(), "One of processes failed." def main(): for frame in range(set.frames): run( [ frame ] ) if __name__ == '__main__': startTime = datetime.datetime.now() #main_mp() # multiprocessing 1 #10.5 #main_tr() # multithreading main_pool() #4.55 #main() # default serial # 15.65 print(datetime.datetime.now() - startTime) print("--End--")
# settings.py canvasWidth = 500 canvasHeight = 500 fps = 5 seconds = 10 duration = 1 / fps frames = seconds * fps pathExport = '___export/' exportFileName = "export_" exportFileType = "gif"
Stich it all back together as one gif:
export_gif.pyimport settings as set def exportGif(): from drawBot.context.tools.gifTools import generateGif destinationPath = set.pathExport + "/movie.gif" images = [] durations = [] for frame in range(set.frames): path = set.pathExport + set.exportFileName + str(frame) + "." + set.exportFileType images.append(path) durations.append(set.duration) generateGif(images, destinationPath, durations) if __name__ == '__main__': exportGif()
To end with some shameless self promotion
:)
You can find a few example on my instagram account @studio.ratata I'll be posting some more stuff soon what I did with DrawBot and Processing.Have fun with the script!
Tim