1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042 |
- # THIS FILE IS A PART OF VCStudio
- # PYTHON 3
- import os
- import datetime
- import json
- import time
- from subprocess import *
- # GTK module ( Graphical interface
- import gi
- gi.require_version('Gtk', '3.0')
- from gi.repository import Gtk
- from gi.repository import GLib
- from gi.repository import Gdk
- import cairo
- # Own modules
- from settings import settings
- from settings import talk
- from settings import fileformats
- from settings import oscalls
- from project_manager import pm_project
- #UI modules
- from UI import UI_elements
- from UI import UI_color
- from UI import UI_math
- # Studio
- from studio import studio_dialogs
- from studio import analytics
- from studio import story
- # Network / Rendering
- from network import network_renders
- def getnumstr(num):
-
- # This function turns numbers like 1 or 20 into numbers like 0001 or 0020
-
- s = ""
- for i in range(4-len(str(num))):
- s = s + "0"
-
- return s+str(num)
- def getfileoutput(num, FORMAT):
-
- # Function gives an output of a file. From the current frame that's rendering.
- # instead of having frame 1 and format EXR it will give you 0001.exr
-
- s = getnumstr(num)
-
- if FORMAT == "JPEG":
- s = s + ".jpg"
- else:
- s = s + "." + FORMAT.lower()
-
- return s
- def save_settings(win, filename):
-
- ############################################################################
-
- # This function will save the render settings file.
-
- ############################################################################
-
- folder = filename[:filename.rfind("/")]+"/extra"
- savefile = folder+filename[filename.rfind("/"):]+".json"
-
- # First let's make sure that the extra folder exists.
-
- try:
- os.makedirs(win.project+folder)
- except:
- pass
-
- # Then let's write the file in there.
-
- with open(win.project+savefile, 'w') as fp:
- json.dump(win.renders[filename], fp, sort_keys=True, indent=4)
- def layer(win, call):
-
- ##########################################################################
-
- # This file will setup and manage rendering of shots. It's a bit complex
- # in function. I have 2 network scripts at the moment. And it might grow
- # beyond that.
-
- # See:
- # network/during_render.py
- # network/network_renders.py
-
- # This file is the UI part of the process. ( The main UI ) Some beats and
- # peaces will exists in various windows through out the program.
-
- ##########################################################################
-
-
- # Making the layer
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
- win.current['h'])
- layer = cairo.Context(surface)
-
-
- #text setting
- layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
-
- UI_color.set(layer, win, "dark_overdrop")
- layer.rectangle(
- 0,
- 0,
- win.current["w"],
- win.current["h"],
- )
- layer.fill()
-
- #########################################################################
- #
- # THE RENDER PREVIEW THINGY
- #
- #########################################################################
- # Here I want to do a preview that's going to be rendered on the right side
- try:
- the_render = win.renders[list(win.renders.keys())[0]]
- amount_of_frames = the_render["end_frame"] - the_render["start_frame"] + 1
- passed = time.time() - win.render_runtime.get("started_rendering", 0)
- passed = passed*1000000
- if win.render_runtime.get("to_render"):
- longest = passed
- else:
- longest = 0
- save_folder = the_render["save_folder"]
- for i in the_render["analytics"][save_folder].values():
- if i > longest:
- longest = i
- shortest = longest
- for i in the_render["analytics"][save_folder].values():
- if i < shortest:
- shortest = i
- rn_files = []
- preview_image = "horse"
- render = list(win.renders.keys())[0]
- folder = render[:render.rfind("/")]
-
- if "render_preview_hovering" not in win.current:
- win.current["render_preview_hovering"] = False
- write_hovering = False
- for n, frame in enumerate(range(the_render["start_frame"], the_render["end_frame"]+1)):
- f = getfileoutput(frame, the_render["image_format"])
- rn_image = win.project+folder+"/"+save_folder+"/"+f
- if os.path.exists(rn_image):
- rn_files.append(f)
-
- for n, frame in enumerate(range(the_render["start_frame"], the_render["end_frame"]+1)):
- frame_w = (win.current["w"]-630)/amount_of_frames
- frame_h = (win.current["h"]-200)/3
- try:
- frac = the_render["analytics"][save_folder][str(frame)] / longest
- frame_h = frame_h * frac
- except Exception as e:
- frame_h = 0
- if win.render_runtime.get("current_frame", 0) == frame and win.render_runtime.get("to_render"):
- frame_h = (win.current["h"]-200)/3 * (passed / longest)
- frame_h = max(frame_h, frame_w)
- minus_w = 2
- round_r = int((frame_w-2)/2)
- if frame_w < 5:
- minus_w = -1
- round_r = 0
- f = getfileoutput(frame, the_render["image_format"])
-
- UI_color.set(layer, win, "node_background")
- if f not in rn_files:
- UI_color.set(layer, win, "dark_overdrop")
- if the_render["analytics"][save_folder].get(str(frame)) == shortest:
- UI_color.set(layer, win, "node_blendfile")
- if win.render_runtime.get("current_frame", 0) == frame and win.render_runtime.get("to_render"):
- UI_color.set(layer, win, "progress_active")
- if the_render["analytics"][save_folder].get(str(frame)) == longest:
- UI_color.set(layer, win, "node_badfile")
- if int(win.current["frame"]/2) % (len(rn_files)) == frame\
- and not win.current["render_preview_hovering"]:
- UI_color.set(layer, win, "progress_active")
- if 580+(n*frame_w) < win.current["mx"] < 580+(n*frame_w)+frame_w:
- UI_color.set(layer, win, "progress_active")
- preview_image = getfileoutput(frame, the_render["image_format"])
- if str(frame) in the_render["analytics"][save_folder]:
- write_hovering = True
- UI_elements.tooltip(win, "Fra:"+str(frame)+"\n"+f+"\n"+UI_math.timestring(the_render["analytics"][save_folder].get(str(frame))/1000000))
- elif not write_hovering:
- write_hovering = False
- UI_elements.roundrect(layer, win,
- 580+(n*frame_w),
- 100+(win.current["h"]-200-frame_h),
- frame_w-minus_w,
- frame_h,
- int((frame_w-2)/2))
-
-
- win.current["render_preview_hovering"] = write_hovering
-
-
- rn_image = win.project+folder+"/"+save_folder+"/"+preview_image
- # CLIP
- UI_elements.roundrect(layer, win,
- 580,
- 100,
- win.current["w"] - 630,
- int((win.current["h"]-200)/3*1.9),
- 10,
- fill=False)
- layer.clip()
-
- if os.path.exists(rn_image):
- UI_elements.image(layer, win, rn_image,
- 580,
- 100,
- win.current["w"] - 630,
- int((win.current["h"]-200)/3*1.9),
- cell="render_preview")
- else:
- n = int(win.current["frame"]/2) % (len(rn_files))
- f = rn_files[n]
- rn_image = win.project+folder+"/"+save_folder+"/"+f
- UI_elements.image(layer, win, rn_image,
- 580,
- 100,
- win.current["w"] - 630,
- int((win.current["h"]-200)/3*1.9),
- cell="render_preview")
-
- layer.reset_clip()
- if win.render_runtime.get("to_render"):
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(50,
- win.current["h"]-30)
- layer.show_text(win.render_runtime.get("current_progress", ""))
- except Exception as e:
- print(e)
-
- #########################################################################
- #
- # THE RENDER MENU
- #
- #########################################################################
-
-
- UI_color.set(layer, win, "node_background")
- UI_elements.roundrect(layer, win,
- 310-250,
- 100,
- 500,
- win.current["h"]-200,
- 10)
-
- # Documentation entry
- def do():
- def after(win, var):
- pass
-
- studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_render"))
-
- UI_elements.roundrect(layer, win,
- 310-250,
- win.current["h"]-140,
- 40,
- 40,
- 10,
- do,
- "question")
-
- is_rendering = False # This will determen whether
-
- for render in win.renders:
- if win.renders[render]["rendering"]:
- is_rendering = True
-
- if not is_rendering:
- # Render button
- def do():
-
- # This here will launch a script that will be on it's on from now
- # on. See:
- # network/during_render.py
- try:
- with open(win.project+"/render_runtime.json") as json_file:
- runtime = json.load(json_file)
- except:
- runtime = {}
- runtime["to_render"] = True
- with open(win.project+"/render_runtime.json", 'w') as fp:
- json.dump(runtime, fp, indent=4)
-
- Popen(["python3", "network/during_render.py", win.project, oscalls.get_current_blender(win)])
-
-
- UI_elements.roundrect(layer, win,
- 310-20,
- win.current["h"]-140,
- 40,
- 40,
- 10,
- button=do,
- icon="right")
- else:
- # Stop Render button
-
- def do():
-
- network_renders.stop_render(win)
-
-
- UI_elements.roundrect(layer, win,
- 310-20,
- win.current["h"]-140,
- 40,
- 40,
- 10,
- button=do,
- icon="stop")
- def do():
-
- os.system("gnome-terminal -- python3 "+os.getcwd()+"/network/render_viewer.py "+win.project)
-
-
- UI_elements.roundrect(layer, win,
- 310-20-40,
- win.current["h"]-140,
- 40,
- 40,
- 10,
- button=do,
- icon="analytics")
-
- # Exit button
- def do():
- win.current["calls"][call]["var"] = False
-
-
- UI_elements.roundrect(layer, win,
- 100+420,
- win.current["h"]-140,
- 40,
- 40,
- 10,
- button=do,
- icon="cancel",
- tip=talk.text("cancel"),
- url="render")
-
-
- x = 70
- y = 100 + 10
- width = 500 - 20
- height = win.current["h"]-200 - 20
-
- UI_elements.roundrect(layer, win,
- x,
- y,
- width,
- height-60,
- 10,
- fill=False)
- layer.clip()
-
- clip = [
- x,
- y,
- width,
- height-60]
-
-
-
-
- # Let's get the filename of the current file that we want to setup.
- filename = win.current["renders_window"]["filename"]
-
- # So this window could be accessed from both main window and from the script.
- # One is to see where each render is. And ther other is to configure and add
- # renders to the list.
-
- if filename:
-
- # Basically if any file is inputted. It means that it's to configure.
- # but sometimes. ( I'm tyring to see myself using it ) the user will
- # click on the render button to just access the render. And to hell with
- # it. Let's make the filename variable the selection of the file.
-
- if filename not in win.renders:
-
- # So on the initialization we want to do a couple of things.
- # First of which will be to get render settings data from the
- # blend file.
-
- # I think a quick bpy script could do.
- # See:
- # studio/bpy_get_render_settings.py
-
- blenderpath = oscalls.get_current_blender(win)
- blend = win.project+filename
-
- checkframes = Popen([blenderpath, "-b", blend , "-P",
- os.getcwd()+"/studio/bpy_get_render_settings.py"],stdout=PIPE, universal_newlines=True)
- checkframes.wait()
- checkstring = checkframes.stdout.read()
-
- # We are going to need the following options.
-
- start_frame = 0
- end_frame = 250
- image_format = "PNG"
- save_folder = "storyboard"
-
-
- for line in checkstring.split("\n"):
-
- if line.startswith("Start_frame"):
- try:
- start_frame = int(line[line.find(":")+1:])
- except:
- pass
-
- if line.startswith("End_frame"):
- try:
- end_frame = int(line[line.find(":")+1:])
- except:
- pass
-
- # Now since we've got the data. Let's write it to the dictionary first.
-
- win.renders[filename] = {
- "start_frame" :start_frame , # The frame we want to start on
- "end_frame" :end_frame , # The frame we want to end on
- "image_format" :image_format, # What format to save the images
- "save_folder" :save_folder , # Into what folder to save images
- "clean_folder" :False , # Whether to delete current frames before rendering
- "current_frame":0 , # What is current frame rendering
- "rendering" :False , # Whether it's currently rendering
- "analytics" :{} # Times of each frame
- }
-
- # Now in order not to loose the data immediatly. We are going to need
- # to add the filename into a special file.
-
- s = open(win.project+"/set/active_renders.data", "a")
- s.write(filename+"\n")
- s.close()
-
- # Also we want to make a little json file in the extra folder of
- # the shot. This will contain our settings. And the file will be
- # read by the renderer script while it's running. It has to be on
- # it's own. So it's good to have extendable files.
-
- save_settings(win, filename)
-
- # Now let's get to the actuall UI of the stuff. Basically I want it to
- # always give us a list of the currently set renders. And one of them
- # might be selected and expendet to see they settings / current data.
-
- # Setting up the scroll
- if "render" not in win.scroll:
- win.scroll["render"] = 0
-
- current_Y = 0
-
- # So let's do this.
-
- is_rendering = False # This will determen whether
-
- # Before we dive into settings and graphs. Let's make a deletion
- if 65535 in win.current["keys"] and not win.renders[win.current["renders_window"]["filename"]]["rendering"]:
- try:
- del win.renders[win.current["renders_window"]["filename"]]
-
- active_renders = open(win.project+"/set/active_renders.data")
- active_renders = active_renders.read()
- active_renders = active_renders.split("\n")
-
- s = open(win.project+"/set/active_renders.data", "w")
-
- for i in active_renders:
- if i != win.current["renders_window"]["filename"] and i:
- s.write(i+"\n")
-
- s.close()
-
- except:
- pass
- win.current["renders_window"]["filename"] = ""
- win.current["keys"] = []
-
- for render in win.renders:
-
- # Let's get a shot name for each render.
-
- shot = render[:render.rfind("/")].replace("/rnd", "")
- blend = render[render.rfind("/"):]
-
- tip = (shot+blend).replace("/", "", 1).replace("/", " | ")
-
- if win.renders[render]["rendering"]:
- tip = win.renders[render]["rendering"]
-
- def do():
- win.current["renders_window"]["filename"] = render
-
- UI_elements.roundrect(layer, win,
- x,
- y+current_Y+win.scroll["render"],
- width,
- 80,
- 10,
- button=do,
- tip=tip,
- clip=clip)
-
- # I think the render logo could be cool.
-
- UI_elements.image(layer, win,
- "settings/themes/"+win.settings["Theme"]+"/icons/render.png",
- x+5, y+current_Y+win.scroll["render"]+5, 40, 40)
-
- # And the name of the shot
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(x+60,
- y+current_Y + win.scroll["render"]+30)
- layer.show_text((shot+blend).replace("/", "", 1).replace("/", " | "))
-
- # And let's draw the fraction
-
- fraction = (win.renders[render]["current_frame"] - win.renders[render]["start_frame"])\
- / (win.renders[render]["end_frame"] - win.renders[render]["start_frame"])
-
- fraction = max(0,min(1, fraction))
- if fraction:
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x+20,
- y+current_Y + win.scroll["render"]+55,
- width-40,
- 0,
- 5)
- UI_color.set(layer, win, "progress_active")
- UI_elements.roundrect(layer, win,
- x+20,
- y+current_Y + win.scroll["render"]+55,
- (width-40)*fraction,
- 0,
- 5)
-
- # Now selection. When you click on one you expend it. And you can see
- # what settings are inside.
-
- if win.current["renders_window"]["filename"] == render:
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x,
- y+current_Y+win.scroll["render"],
- width,
- 80,
- 10,
- fill=False)
- layer.stroke()
-
- current_Y = current_Y + 90
-
-
-
- # We are going to have 2 differnt UI's for those who are rendering
- # and those who are not rendering.
-
- if not win.renders[render]["rendering"]:
-
- # We need to choose the folder of where the given render will be done.
- # For the user tho I don't think nessesary to understand that it's a
- # folder nessesary. They will see 4 circles. 4 render qualities. And
- # will decide stuff based on that.
-
- fouricons = [ "storyboard", "opengl", "test_rnd", "rendered"]
-
- for num, f in enumerate(fouricons):
- if f == win.renders[render]["save_folder"]:
-
- UI_color.set(layer, win, "progress_time")
- UI_elements.roundrect(layer, win,
- x+20+(40*num),
- y+current_Y + win.scroll["render"],
- 40,
- 40,
- 10)
-
- def do():
- win.renders[render]["save_folder"] = f
- save_settings(win, render)
-
- UI_elements.roundrect(layer, win,
- x+20+(40*num),
- y+current_Y + win.scroll["render"],
- 40,
- 40,
- 10,
- button=do,
- icon=f,
- tip=f)
-
- # Here also I want to have a little clean icon. This will make sure
- # to clean the current frames that are currently inside the folder.
- # I know it's slightly counter intuitive compared to the rest of
- # the program in that it's better not to give the user the ability
- # to delete any actuall files. But in this case it makes a bit
- # sense. Since for the user rendering again is like replacing the
- # previous files with new ones. And the algorythm always renders
- # from the last frame in the folder. So it never deletes anything
- # by defaul. So I guess a button to clean frames could be a good
- # thing.
-
- if win.renders[render]["clean_folder"]:
-
- UI_color.set(layer, win, "progress_time")
- UI_elements.roundrect(layer, win,
- x+width-40,
- y+current_Y + win.scroll["render"],
- 40,
- 40,
- 10)
-
- def do():
- win.renders[render]["clean_folder"] = not win.renders[render]["clean_folder"]
- save_settings(win, render)
-
- UI_elements.roundrect(layer, win,
- x+width-40,
- y+current_Y + win.scroll["render"],
- 40,
- 40,
- 10,
- button=do,
- icon="clean",
- tip=talk.text("clean_render_folder"))
-
-
- current_Y = current_Y + 50
-
-
- # Now let's put the settings them selves.
- # First thing is we need start and end frames. And we also need it
- # somehow readable for the user.
-
- # I will probably need this.
- def is_number(string):
- try:
- int(string)
- return True
- except:
- return False
-
- # START FRAME
-
- UI_elements.text(layer, win, render+"start_frame",
- x+10,
- y+current_Y+win.scroll["render"],
- 100,
- 40,
- set_text=str(win.renders[render]["start_frame"]),
- tip=talk.text("rendering_start_frame"))
-
- if win.text[render+"start_frame"]["text"] != str(win.renders[render]["start_frame"])\
- and is_number(win.text[render+"start_frame"]["text"]):
- def do():
- win.renders[render]["start_frame"] = int(win.text[render+"start_frame"]["text"])
- save_settings(win, render)
-
-
- UI_elements.roundrect(layer, win,
- x+70,
- y+current_Y+win.scroll["render"],
- 40,
- 40,
- 10,
- button=do,
- icon="ok",
- tip=talk.text("checked"))
-
-
-
-
- # FILE FORMATS
-
- # I will not add any video files since the algoryhm will require
- # actuall frames to be stored as separate files. This will insure
- # that ALL frames were rendered. And in case of crash the algorythm
- # will pick up from a previous frame in a folder. With video is not
- # only impossible. But in case of a crash with video all the previous
- # frames will be lost.
-
- # What I want to do is to ejucate the user on the Open Formats.
- # You know using OGG video instead of MP4 and stuff like that.
- # For images there are the same types of Open Formats. The point
- # is that these formats could be made and played using entirelly
- # free software.
-
- # I will let selection of formats that are not in the list but I
- # will mark them as non-recommended. I will do it like so.
-
- # [ <start frame> ] [ PNG ] [ <png frame>
-
- # V PNG ?
- # V JPEG ?
- # V EXR ?
- # X HDR ?
-
- # And so on and forth. You can see that HDR is marked with an X
- # it will be a button linking to the :
- linfo = "http://www.linfo.org/free_file_format.html"
- # so the user could read a full document describing desisions
- # about the formats.
-
-
-
- formats = {
- "PNG" : [True, "Image PNG", "https://en.wikipedia.org/wiki/Portable_Network_Graphics"],
- "JPEG": [True, "Image JPEG", "https://en.wikipedia.org/wiki/JPEG"],
- "EXR" : [True, "Open EXR", "https://en.wikipedia.org/wiki/OpenEXR"],
- "HDR" : [False,"Radiance HDR", "https://en.wikipedia.org/wiki/RGBE_image_format"],
- "BMP" : [False,"Microsoft BMP", "https://en.wikipedia.org/wiki/BMP_file_format"],
- "TGA" : [False,"Truevision TGA", "https://en.wikipedia.org/wiki/Truevision_TGA"],
- "TIFF": [False,"Tiff", "https://en.wikipedia.org/wiki/Tagged_Image_File_Format"]
- }
-
- if "selecting_render_file_format" not in win.current:
- win.current["selecting_render_file_format"] = False
-
- def do():
- win.current["selecting_render_file_format"] = not win.current["selecting_render_file_format"]
- if win.current["selecting_render_file_format"]:
- win.scroll["render"] = win.scroll["render"]-50*len(formats)
- win.current["LMB"] = False
- win.previous["LMB"] = False
-
- UI_elements.roundrect(layer, win,
- x+120,
- y+current_Y + win.scroll["render"],
- 235,
- 40,
- 10,
- button=do,
- tip=talk.text("rendering_file_format"))
-
- currentformat = win.renders[render]["image_format"]
-
-
- if not win.current["selecting_render_file_format"]:
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(310-len(formats[currentformat][1])*6,
- y+current_Y + win.scroll["render"]+30)
- layer.show_text(formats[currentformat][1])
-
-
-
- # END FRAME
- UI_elements.text(layer, win, render+"end_frame",
- x+365,
- y+current_Y+win.scroll["render"],
- 100,
- 40,
- set_text=str(win.renders[render]["end_frame"]),
- tip=talk.text("rendering_end_frame"))
-
- if win.text[render+"end_frame"]["text"] != str(win.renders[render]["end_frame"])\
- and is_number(win.text[render+"end_frame"]["text"]):
- def do():
- win.renders[render]["end_frame"] = int(win.text[render+"end_frame"]["text"])
- save_settings(win, render)
-
- UI_elements.roundrect(layer, win,
- x+215+210,
- y+current_Y+win.scroll["render"],
- 40,
- 40,
- 10,
- button=do,
- icon="ok",
- tip=talk.text("checked"))
-
-
- current_Y = current_Y + 50
-
-
-
- if win.current["selecting_render_file_format"]:
-
- for num, f in enumerate(formats):
-
- if f == win.renders[render]["image_format"]:
-
- UI_color.set(layer, win, "progress_time")
- UI_elements.roundrect(layer, win,
- x+120,
- y+current_Y + win.scroll["render"],
- 235,
- 40,
- 10)
-
-
- def do():
- win.renders[render]["image_format"] = f
- save_settings(win, render)
- win.current["selecting_render_file_format"] = False
-
- UI_elements.roundrect(layer, win,
- x+120,
- y+current_Y + win.scroll["render"],
- 235,
- 40,
- 10,
- button=do)
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(310-len(formats[f][1])*6,
- y+current_Y + win.scroll["render"]+30)
- layer.show_text(formats[f][1])
-
- # RECCOMENDATION
-
- if formats[f][0]:
- rec = talk.text("recommended_yes")
- ic = "ok"
- else:
- rec = talk.text("recommended_not")
- ic = "cancel"
-
- def do():
- os.system("xdg-open "+linfo)
-
- UI_elements.roundrect(layer, win,
- x+10,
- y+current_Y + win.scroll["render"],
- 40,
- 40,
- 10,
- button=do,
- icon=ic,
- tip=rec)
-
- # WIKIPEDIA ABOUT THE FORMAT
-
- def do():
- os.system("xdg-open "+formats[f][-1])
-
- UI_elements.roundrect(layer, win,
- x+430,
- y+current_Y + win.scroll["render"],
- 40,
- 40,
- 10,
- button=do,
- icon="question",
- tip="Wikipedia")
-
- current_Y = current_Y + 50
-
- else:
-
- # And here comes the UI of when it's during RENDERING
-
- # First thing will be to draw a little graph. This will show current
- # frame and analytics data about render times.
-
- UI_color.set(layer, win, "dark_overdrop")
- layer.rectangle(
- x+5,
- y+current_Y+win.scroll["render"],
- width-10,
- 100)
- layer.fill()
-
- for frame in range(win.renders[render]["start_frame"], win.renders[render]["end_frame"]+1):
-
- numofis = win.renders[render]["end_frame"] - win.renders[render]["start_frame"]
-
- if frame == win.renders[render]["current_frame"]:
-
- UI_color.set(layer, win, "progress_time")
- layer.rectangle(
- x+5+(width-10)/numofis*(frame-1),
- y+current_Y+win.scroll["render"],
- (width-10)/numofis,
- 100)
- layer.fill()
-
- # Now I want to be able to interact with the graph. For this I want to
- # add a little mouse sensitive region. That will give me data about the
- # current frame. In a tooltip?
-
- if int(win.current["mx"]) in range(int(x+5+(width-10)/numofis*frame),int(x+5+(width-10)/numofis*frame+(width-10)/numofis))\
- and int(win.current["my"]) in range(int(y+current_Y+win.scroll["render"]), int(y+current_Y+win.scroll["render"]+100)):
-
- UI_color.set(layer, win, "progress_background")
- layer.move_to(x+5+(width-10)/numofis*(frame-0.5),
- y+current_Y+win.scroll["render"]
- )
- layer.line_to(
- x+5+(width-10)/numofis*(frame-0.5),
- y+current_Y+win.scroll["render"]+100
- )
- layer.stroke()
- if win.renders[render]["save_folder"] in win.renders[render]["analytics"]:
- if str(frame) in win.renders[render]["analytics"][win.renders[render]["save_folder"]]:
-
- value = win.renders[render]["analytics"][win.renders[render]["save_folder"]][str(frame)]
-
- UI_elements.tooltip(win, UI_math.timestring(value/1000000))
-
- # Now let's draw a graph. I love graphs. They are cool AF. First of all tho
- # we need to know the maximum value. Because who know how long was the render
-
- mx = 0
- allvalues = []
- if win.renders[render]["save_folder"] in win.renders[render]["analytics"]:
- for v in win.renders[render]["analytics"][win.renders[render]["save_folder"]]:
- mx = max(win.renders[render]["analytics"][win.renders[render]["save_folder"]][v], mx)
- allvalues.append(win.renders[render]["analytics"][win.renders[render]["save_folder"]][v])
-
- UI_color.set(layer, win, "progress_background")
- layer.move_to(x+5, y+current_Y+win.scroll["render"]+100)
- for frame in range(win.renders[render]["start_frame"], win.renders[render]["end_frame"]+1):
- numofis = win.renders[render]["end_frame"] - win.renders[render]["start_frame"]
- if win.renders[render]["save_folder"] in win.renders[render]["analytics"]:
- if str(frame) in win.renders[render]["analytics"][win.renders[render]["save_folder"]]:
-
- value = win.renders[render]["analytics"][win.renders[render]["save_folder"]][str(frame)]
-
- layer.line_to(
- x+5+(width-10)/numofis*(frame-0.5),
- (y+current_Y+win.scroll["render"]+100)-(100/mx*value)
- )
- layer.stroke()
-
- current_Y = current_Y + 110
-
- # Now let's put out some data in the text format. For the user to
- # know stuff he or she might want to know.
-
- # AVARAGE TIME
-
- avarage = 0
- try:
- avarage = sum(allvalues) / len(allvalues)
- except:
- pass
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(x+10,
- y+current_Y + win.scroll["render"]+30)
- layer.show_text(talk.text("render_avarage_time")+" "+UI_math.timestring(avarage/1000000))
-
- current_Y = current_Y + 40
-
- # REMAINING TIME
-
- remaining = avarage * (win.renders[render]["end_frame"] - win.renders[render]["current_frame"] + 1)
- remaining = remaining/1000000
- remaining = remaining - (time.time() - win.render_runtime.get("started_rendering", 0))
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(x+10,
- y+current_Y + win.scroll["render"]+30)
- layer.show_text(talk.text("render_remaining_time")+" "+UI_math.timestring(remaining))
-
- current_Y = current_Y + 40
-
-
- else:
-
- current_Y = current_Y + 85
-
- ###########################
-
- UI_elements.scroll_area(layer, win, "render",
- x,
- y,
- width,
- height-60,
- current_Y,
- bar=True,
- mmb=True,
- url="render"
- )
-
-
- return surface
|