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 yourRAARCGEN.__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 passingFalse
in it will cause Cinema 4D to more frequently try to update the cache the node, or in other words callObjectData.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 expressiondoc = 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 useGeListNode.GetDocument()
instead - like sodoc = 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 aTagData
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 -
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!