Render filtered Hardware Preview



  • Hi,

    I'm starting to feel pretty stupid. I'm trying to do a hardware preview render using the nice new filter options added in C4D S22.

    My code looks roughly like so, here for use in Script Manager:

    import c4d
    
    def CreateDefaultRenderData():
        rd = c4d.documents.RenderData()
        if rd is None:
            return None
        vp = c4d.BaseList2D(c4d.RDATA_RENDERENGINE_PREVIEWHARDWARE)
        if vp is None:
            return None
        rd.InsertVideoPostLast(vp)
        vp[c4d.VP_PREVIEWHARDWARE_ONLY_GEOMETRY] = True ### THIS IS WHAT I AM ACTUALLY INTERESTED IN
        rd[c4d.RDATA_RENDERENGINE] = c4d.RDATA_RENDERENGINE_PREVIEWHARDWARE
        rd[c4d.RDATA_XRES] = 600
        rd[c4d.RDATA_YRES] = 600
        return rd
    
    def main():
        docClone = doc.GetClone()
        rdPreview = CreateDefaultRenderData()
        if rdPreview is None:
            return
        rdPreview[c4d.RDATA_XRES] = 600
        rdPreview[c4d.RDATA_YRES] = 600
        bmPreview = c4d.bitmaps.BaseBitmap()
        bmPreview.Init(rdPreview[c4d.RDATA_XRES], rdPreview[c4d.RDATA_YRES])
        result = c4d.documents.RenderDocument(docClone, rdPreview.GetData(), bmPreview, c4d.RENDERFLAGS_EXTERNAL, th=None)
        if result == c4d.RENDERRESULT_OK:
            c4d.bitmaps.ShowBitmap(bmPreview)
        # insert render settings for comparison
        rdPreview.SetName('Test Settings')
        doc.InsertRenderData(rdPreview)
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()
    

    I'm trying to get the VP_PREVIEWHARDWARE_ONLY_GEOMETRY flag to work.
    The funny thing is, if I manually render the active scene with the render settings created by above script, I do get the result I want. But not so in the image rendered by the script.

    ... ... while writing these lines, it struck me. And indeed I can make it work by inserting the new RenderData into the cloned document and making it active. So my question is actually no longer, how to make it work. But more, why do I need to insert the RenderData into the scene? I mean, it's passed to RenderDocument separately and I doubt, I saw an SDK example explicitly inserting new RenderData for such purposes. But then again, as I said in the beginning, I'm starting to feel stupid and most likely I am.

    Cheers



  • Hi,

    on R21 this seems to work just fine (minus the new flag). So this might be a bug. Apart from this, have you tested if this is related to any lifetime shenanigans of your RenderData node, i.e. if the node is not alive anymore when the passed document is being cloned for rendering? For example by attaching to just a document, not the document you want to render.

    Cheers,
    zipit



  • In the script above I create the RenderData only for the purpose of rendering, so I doubt, it's a lifetime issue.

    And in S22 it also works without inserting the RenderData, it's just the new filter flags that somehow seem to be taken from the active document's render settings. At least that's what I think based on further testing.



  • Hi @a_block I hope you are fine :)

    In order to use the Preview Render you have to additionally pass RENDERFLAGS_PREVIEWRENDER

    result = c4d.documents.RenderDocument(docClone, rdPreview.GetData(), bmPreview, c4d.RENDERFLAGS_PREVIEWRENDER | c4d.RENDERFLAGS_EXTERNAL, th=None)
    

    Work as expected.

    Cheers,
    Maxime.



  • I'm sorry, but here it's not.
    I had tried the RENDERFLAGS_PREVIEWRENDER flag before. It doesn't change anything. At least not in my 22.116. And if I insert the RenderData as described, it works without RENDERFLAGS_PREVIEWRENDER flag.
    But one has to be careful with testing. If the currently active scene has such flags set, too, then it may seems as if it works, while it actually is not working.
    Is it documented somewhere, that this flag would be needed?

    Cheers



  • @m_adam: Sure, I'm fine, and I hope, so is the entire SDK Team :)
    Thanks for asking, Maxime.



  • @a_block said in Render filtered Hardware Preview:

    But one has to be careful with testing. If the currently active scene has such flags set, too, then it may seems as if it works, while it actually is not working.

    As always you are right, Im going to keep my research then :)



  • If "always" means one in a million, then maybe.



  • Yes, all SDK team members are fine :D

    I can only confirm the issue here, and it was introduced in S22 with the new ViewPort stuff just in case you want to do different codes for different versions.
    The problem is that internally the new Viewport Render, is really just a mirror of what you see in the Viewport. And by default, the Viewport retrieves its data from the active BaseDraw of the document the Viewport is supposed to represent.
    And by default (and here come the issue) this BaseDraw setting retrieves the active render setting when you ask for a render outside of the ViewPort windows.

    So the current workaround is to set the render setting as active as bellow.

    import c4d
    
    def main():
        docClone = doc.GetClone()
        
        # Setup RenderData
        rdPreview = c4d.documents.RenderData()
        rdPreview[c4d.RDATA_RENDERENGINE] = c4d.RDATA_RENDERENGINE_PREVIEWHARDWARE
        rdPreview[c4d.RDATA_XRES] = 600
        rdPreview[c4d.RDATA_YRES] = 600
        
        # Uncomments those 2 lines to make it work
        # docClone.InsertRenderData(rdPreview)
        # docClone.SetActiveRenderData(rdPreview)
        
        # Setup Viewport Render
        vp = c4d.BaseList2D(c4d.RDATA_RENDERENGINE_PREVIEWHARDWARE)
        rdPreview.InsertVideoPostLast(vp)
        vp[c4d.VP_PREVIEWHARDWARE_ONLY_GEOMETRY] = True
        
        # Setup target BMP
        bmPreview = c4d.bitmaps.BaseBitmap()
        bmPreview.Init(rdPreview[c4d.RDATA_XRES], rdPreview[c4d.RDATA_YRES])
        
        # Render
        result = c4d.documents.RenderDocument(docClone, rdPreview.GetData(), bmPreview, c4d.RENDERFLAGS_EXTERNAL, th=None)
        if result == c4d.RENDERRESULT_OK:
            c4d.bitmaps.ShowBitmap(bmPreview)
            
    if __name__=='__main__':
        main()
    

    I've open a bug report about it.

    Cheers,
    Maxime.



  • Thanks for validating my assumptions. Much appreciated.
    Yes, I already have multiple code branches and for S22 my workaround looks as described. Because it doesn't hurt to insert the RenderData in this case, it doesn't even need multiple branches.
    Thanks for looking into it, Maxime.

    Is this going to be fixed in a future version?