Solved Run plugin every frame

Hi,

In short I build a plugin that's the same as the tiling camera in de C4D Lib. However the plugin does not update when it is not selected. Same thing when I render. How can I update / execute the plugin on every frame or change in the viewport like an xpresso tag for example.

Below a small part of the code. The tiling camera is just 1 function of many.

class RAARCGEN(plugins.ObjectData):
    if licenpass:
        include ('id')
        include ('reninit')
        include('iconchange')
        include('initvar')
        include('finalrender')
        #include('proxy')
        hashpass=False
        def __init__(self):
            self.SetOptimizeCache(True)
        def Message(self, node, type, data):
            data = node.GetDataInstance()
            #for name in searchNames(type):
            #    print type, name
            global doc
            doc = c4d.documents.GetActiveDocument()      
            if type==c4d.MSG_MENUPREPARE:
                InitVariables(doc,data)
            elif type==1036465: #trigger for placing object in the include/exclude field
                RelisInExc(doc, data)
            elif type==1036464: #trigger for removing object in the include/exclude field
                RelisInExc(doc, data)
            #elif type==431000094 or type==c4d.MSG_DESCRIPTION_COMMAND:
               #updatemodule(node,self)
            return True
        
        def Init(self, node):
            print ("test")
            return True
        
        def GetDEnabling(self, node, id, t_data, flags, itemdesc):
            data = node.GetDataInstance()
            if data is None: return
            ID = id[0].id
            updatemodule(node,self)
            #if (ID==FR_MAN):
            #    updatemodule(node,self)
            if (ID in {RENDER_ENGINE , RENDER_Q , GI_ENABLED , AO_ENABLED,FR_RENDER_Q} ):
                if data.GetBool(REN_BOOL) == False: return False
            if (ID in {MY_SUBBOX} ):
                if data.GetBool(ONOFF_ENABLED) == False: return False
            if (ID in {FILELOC , FILENAME , FILESUB , DESKPATH, FILCUST, FILEPATH} ):
                if data.GetBool(FILE_BOOL) == False: return False
            if (ID in {CUSRENTEXT , RENDER_SIZE , CUSSIZEW , CUSSIZEH, CUSRATIOLOCK, CUSRENUNIT, CUSRESO , BACKRENFILE , BACKRENRES , BACKRENVIS, FR_RENDER_SET ,TILINGCAM,TILINGR,TCAMSRC,TCAMTAR,CAMAXIS,RENDER_SIZE_TILE,FRAME_SELEC,MFRAMESEL}):
                if data.GetBool(SIZEMAN) == False: return False
            if (ID in {ABOUT_TEXT} ):
                return False
            if (ID in {PROXY_BOOL}):
                if data.GetBool(PROXY_BOOL)==False:
                    checkLayer = doc.GetLayerObjectRoot().GetDown()
                    while checkLayer:
                        if checkLayer.GetName() == 'Proxy viewport' or checkLayer.GetName() == 'Proxy render':
                            newLayer = checkLayer
                            newLayer.Remove()
                        checkLayer = checkLayer.GetNext()
            if (ID in {FRPROXYFORCERENDER,PROXYFORCEVIEW,PROXYFORCERENDER,OBJECT1_BOOL,OBJECT2_BOOL,OBJECT3_BOOL,OBJECT4_BOOL,OBJECT5_BOOL,OBJECT6_BOOL,OBJECT7_BOOL,OBJECT8_BOOL,OBJECT9_BOOL,OBJECT10_BOOL,
                       PROXY1,PROXY2,PROXY3,PROXY4,PROXY5,PROXY6,PROXY7,PROXY8,PROXY9,PROXY10,
                       OBJECT1,OBJECT2,OBJECT3,OBJECT4,OBJECT5,OBJECT6,OBJECT7,OBJECT8,OBJECT9,OBJECT10}):
                if data.GetBool(PROXY_BOOL)==False: return False
                  
                     
                return True
            return True
            
if __name__ == "__main__":
    if licenpass:
        path, file = os.path.split(__file__)
        bmp = bitmaps.BaseBitmap()
        bmp.InitWith(os.path.join(path, "res", "Fire_base.png"))
        plugins.RegisterObjectPlugin(id=PLUGIN_ID, str=PLUGIN_NAME,
                                    g=RAARCGEN,
                                    description="raarc", icon=bmp,
                                    info=c4d.OBJECT_GENERATOR)
    

Many thanx in advance

Hi @RneCGI,

welcome to the forum and the Cinema 4D community. It is unfortunately not possible to answer your question clearly since you left out the relevant main execution method(s) of your implementation (e.g., ObjectData.GetVirtualObjects, etc.).

But you are invoking ObjectData.SetOptimizeCache(True) in your RAARCGEN.__init__() which will tell Cinema to optimize the cache of an object by only invoking the building of the cache when the data container of the node is dirty, i.e., when the user changed a parameter. Leaving out this call or passing False in it will cause Cinema 4D to more frequently try to update the cache the node, or in other words call ObjectData.GetVirtualObjects, .GetContour(), .ModifyObject() or .ModifyParticles() more frequently, depending on the flags with which you registered your plugin. You can read more about cache optimization here.

In your RAARCGEN.Message() you have also the expression doc = c4d.documents.GetActiveDocument(), which you should not do, since there is no guarantee that the active document is the document your node is located in, because documents also are executed when they are not the active document (in rendering a document is being cloned for example). So you should use GeListNode.GetDocument() instead - like so doc = node.GetDocument().

Last but not least it seems a bit odd to me that you are using an ObjectData implementation to replicate a tiling camera setup. This should more be the job of a TagData solution. If you are planning on returning a camera object as part of the cache of your node data implementation, I would advise against it. This could technically be done, but it would break with Cinema's design as it would seal of setting that camera as the render camera as something that can only be done by your implementation.

Which brings us back to the point that your example does not show or indicate your core logic, which makes it hard to give here good advice. So, if my answer did not bring any clarification for you, I would ask you to provide either a more extensive example or send it to sdk_support(at)maxon.net, in case you are not at liberty to share all of your code.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

After a few mails with Ferdinand I switched to a Tag plugin solution. This does the job perfectly.
So the solution was not to use an Object data solution but a TagData.

Thanx!