Getting Render Progress
-
Hello,
I'd like to write a script that starts a render and prints its progress.I found this topic on the forum:
Render to Picture Viewer and RenderDocument woesThe script below (based on the one from the aforementioned topic) does a good job with determining when a render has completed by starting a new thread, but how can I use it to determine the current render progress?
import c4d import os,time,_thread def isRendering(time,os) : print(time.ctime()) while c4d.CheckIsRunning ( c4d.CHECKISRUNNING_EXTERNALRENDERING ) : print("render in progress...") time.sleep(3) print(time.ctime()) print("render complete.") def main() : c4d.CallCommand(12099) #Render to Picture Viewer if c4d.CheckIsRunning ( c4d.CHECKISRUNNING_EXTERNALRENDERING ) : _thread.start_new_thread(isRendering,(time,os)) if __name__=='__main__': main()
Thank you!
-
Hi,
the best way to do it is to use the progress hooks functions. We got an example on github.
Be aware that if you want to display the progress using a progress bar, this will not work from the script manager. You must write your own plugins and GeDialog to make it work.
Cheers,
Manuel -
@m_magalhaes
Hi Manuel,
Thank you for the reply! I have found the GitHub example, but it does not show the progress until after the rendering has completed. When it does, it shows it during the "Before Rendering" progress type when I would expect to see it during "During Rendering." As in my original post, I believe starting a new thread is necessary, but I'm not sure how to check on the render progress with this method.Here is the script you recommended turned into a plugin. Also, if it needs to be a plugin to work, could you please make the example on GitHub a plugin?
import c4d PLUGIN_ID = 9102524 class ProgressDialog(c4d.gui.GeDialog): RENDER_TEXT = 1000 RENDER_BUTTON = 1001 def PythonCallBack(self, progress, progress_type): text = str() if progress_type == c4d.RENDERPROGRESSTYPE_BEFORERENDERING: text = "Before Rendering" elif progress_type == c4d.RENDERPROGRESSTYPE_DURINGRENDERING: text = "During Rendering" elif progress_type == c4d.RENDERPROGRESSTYPE_AFTERRENDERING: text = "After Rendering" elif progress_type == c4d.RENDERPROGRESSTYPE_GLOBALILLUMINATION: text = "GI" elif progress_type == c4d.RENDERPROGRESSTYPE_QUICK_PREVIEW: text = "Quick Preview" elif progress_type == c4d.RENDERPROGRESSTYPE_AMBIENTOCCLUSION: text = "AO" # Prints to the console the current progress prog = "ProgressHook called [{0} / p: {1}]".format(text, progress * 100.0) self.SetString(self.RENDER_TEXT,prog) print(prog) def PythonWriteCallBack(self, mode, bmp, fn, mainImage, frame, renderTime, streamnum, streamname): text = str() if mode == c4d.WRITEMODE_STANDARD: text = "Standard" elif mode == c4d.WRITEMODE_ASSEMBLE_MOVIE: text = "Assemble Movie" elif mode == c4d.WRITEMODE_ASSEMBLE_SINGLEIMAGE: text = "Assemble single image" wprog = "ProgressWriteHook called [{0} / p: {1}]".format(text, renderTime) self.SetString(self.RENDER_TEXT,wprog) print(wprog) def CreateLayout(self): self.SetTitle("Render Progress") if self.GroupBegin(id=0, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, title="", rows=1, cols=1, groupflags=c4d.BORDER_GROUP_IN): self.GroupBorderSpace(20, 20, 20, 20) self.AddStaticText(self.RENDER_TEXT, c4d.BFH_CENTER | c4d.BFH_SCALE | c4d.BFV_CENTER | c4d.BFV_SCALE, 600, 20, borderstyle=c4d.BORDER_THIN_IN) self.AddButton(self.RENDER_BUTTON, c4d.BFH_CENTER | c4d.BFH_SCALE | c4d.BFV_CENTER | c4d.BFV_SCALE, initw=0, inith=0, name='RENDER') self.GroupEnd() return True def Render(self): doc = c4d.documents.GetActiveDocument() # Retrieves the current active render settings rd = doc.GetActiveRenderData() # Creates a Multi Pass Bitmaps that will store the render result bmp = c4d.bitmaps.MultipassBitmap(int(rd[c4d.RDATA_XRES]), int(rd[c4d.RDATA_YRES]), c4d.COLORMODE_RGB) if bmp is None: raise RuntimeError("Failed to create the bitmap.") # Adds an alpha channel bmp.AddChannel(True, True) # Renders the document if c4d.documents.RenderDocument(doc, rd.GetData(), bmp, c4d.RENDERFLAGS_EXTERNAL, prog=self.PythonCallBack, wprog=self.PythonWriteCallBack) != c4d.RENDERRESULT_OK: raise RuntimeError("Failed to render the temporary document.") # Displays the render in the Picture Viewer c4d.bitmaps.ShowBitmap(bmp) def Command(self, messageId, bc): if messageId == self.RENDER_BUTTON: self.Render() return True class RenderProgressCommandData(c4d.plugins.CommandData): dialog = None def Execute(self, doc): if self.dialog is None: self.dialog = ProgressDialog() return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaulth=700, defaultw=200) def RestoreLayout(self, sec_ref): if self.dialog is None: self.dialog = ProgressDialog() return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref) if __name__ == "__main__": c4d.plugins.RegisterCommandPlugin(id=PLUGIN_ID, str="RenderProgress", help="Show the current render progress of Cinema 4D.", info=0, dat=RenderProgressCommandData(), icon=None)
Thank you!
-
Hi,
and sorry for the ultra-late reply.
This is blocking the main thread you can't really send anything to update the dialog windows.Cheers,
Manuel -
Hello @blastframe,
I must apologize, I know we took our sweet time with answering this. However, we must move on with that topic, since it has been more than fourteen days since Manuel did provide his last answer. We will consider this thread as solved by Monday the 20th and flag it accordingly. Please feel free to reopen the 'Ask-as-question' status when there are questions left.
Thank you for your understanding,
Ferdinand