Objectdata plugin is not refreshed / updated
-
On 26/04/2013 at 11:07, xxxxxxxx wrote:
Using a link, it works!
Thanks. -
On 26/04/2013 at 13:24, xxxxxxxx wrote:
i am not sure why the flag is not working. please note, that it was only a guess, it is
not guaranteed that the flag is meant to add that special cache rebuilding behaviour.alternatively you could follow just the NodeData.Message() approach., if you want to
maintain the c4d workflow. simply store a reference to the path object in your class
and each time Message() receives a change msgid, test if self.reference is node.GetDown()
and flag your node dirty depending on the result. -
On 26/04/2013 at 13:56, xxxxxxxx wrote:
Thanks for all your help and I understand it was only a guess.
I have to think and of course try out, your other option, the NodeData.message approach.
I have read some other posts about other simular issues
I now better understand and it might be an option, something ScottA posted:
What about triggering a hidden UserData field in your code to update it instead?
https://developers.maxon.net/forum/topic/6070/6249_getcontour-refresh-or-uncache-how&PID=26194#26194 -
On 26/04/2013 at 14:04, xxxxxxxx wrote:
Originally posted by xxxxxxxx
alternatively you could follow just the NodeData.Message() approach., if you want to
maintain the c4d workflow. simply store a reference to the path object in your class
and each time Message() receives a change msgid, test if self.reference is node.GetDown()
and flag your node dirty depending on the result.You mean:
Listen toNodeData.Message
( self , node , type , data )
if self.reference = child object (node.getdown())
set dirty plugin nodeNot quite sure about it, but I''ll give it a try.
-
On 26/04/2013 at 14:18, xxxxxxxx wrote:
i think you mean == instead = and i am not sure about the rest of the line, but despite that
i actually meant the is keyword.def __init__(self) : self.reference = None def Message(self, node, type, data) : if node.getdown() is not self.reference: self.reference = node.GetDown() node.SetDirty(0)
practically you could check first if the msg id is the change msg and only then execute the rest.
you would also have to check the case where the object is the same, but the bc has changed.
for a parametric spline for example which is animated. -
On 26/04/2013 at 14:48, xxxxxxxx wrote:
It is working and more simple then we thought.
All I did was remove the following lines:def __init__(self) :
self.SetOptimizeCache(True)The downside is that Render Active View is not working anymore!
More testing to do.import os import math import sys import c4d from c4d import plugins, utils, bitmaps, gui PLUGIN_ID = 10252501 class SweepObj(plugins.ObjectData) : def GetVirtualObjects(self, op, hierarchyhelp) : # Disabled the following lines because cache flag was set # So the cache build is done before this method is called #dirty = op.CheckCache(hierarchyhelp) or op.IsDirty(c4d.DIRTY_DATA) #if dirty is False: return op.GetCache(hierarchyhelp) #Get the child / parent object (to use as the sweep spline) #Use GetClone so we aren't working on the object itself source = op.GetDown() if (source is None) : return None source = op.GetDown().GetClone() #Create a Circle Primitive to act as the sweep profile circle = c4d.BaseObject(c4d.Osplinecircle) #Set the radius circle[c4d.PRIM_CIRCLE_RADIUS] = 10.0 #Create a new SweepNURBS sweep = c4d.BaseObject(c4d.Osweep) #Insert the source sweep spline under the SweepNURBS source.InsertUnder(sweep) #Insert the circle profile spline under the SweepNURBS circle.InsertUnder(sweep) sweep.Message (c4d.MSG_UPDATE) #update sweep in viewport c4d.EventAdd() #Return the SweepNURBS return sweep if __name__ == "__main__": pluginstr = "SweepObj TEST v01" dir, file = os.path.split(__file__) icon = bitmaps.BaseBitmap() icon.InitWith(os.path.join(dir, "res", "sweepobj.tif")) okyn = plugins.RegisterObjectPlugin(id=PLUGIN_ID, str="SweepObj", g=SweepObj, description="SweepObj", icon=icon, info=c4d.OBJECT_GENERATOR | c4d.OBJECT_INPUT) if (okyn) : print pluginstr + " initialized." else: print "Error initializing " + pluginstr
-
On 26/04/2013 at 14:55, xxxxxxxx wrote:
because you have disabled caching with that if another node is polling your node the node
will always recalculate its output instead of returning its cache when the underlying data
has not changed. -
On 26/04/2013 at 15:06, xxxxxxxx wrote:
Yes, the manual tells us:
The method GetVirtualObjects() is called on each frame and if you don't want to calculate the object on each frame again and again you can still return the cache object with the following code:I tried your option, but without any testing.
That did not solve it. Is 0 the correct flag value to set?
How and when is SetDirty used by Cinema 4d?def Message(self, node, type, data) : node.SetDirty(0) return True
-
On 26/04/2013 at 15:57, xxxxxxxx wrote:
hi,
i didn't actually test my posted code and assumed that a node is notified each time
one of its children changes, however that is not the case (at least not always,
messages tend to be confusing ). long story short here is a working version, i have
actually tested this time it returns a Null when the object has no child and then
alternating a sphere or cube each time the cache is rebuild.the cache is rebuild when either the direct child changes or the direct child is dirty.
import c4d, os, sys from c4d import bitmaps, documents, gui, modules, plugins class fhOdataTestData(plugins.ObjectData) : def __init__(self) : self.reference = None self.toggle = False def GetVirtualObjects(self, node, hierarchyhelp) : if node.GetDown() != self.reference: self.reference = node.GetDown() node.SetDirty(c4d.DIRTY_DATA) elif node.GetDown() and node.GetDown().IsDirty(c4d.DIRTY_DATA) : node.SetDirty(c4d.DIRTY_DATA) if not (node.CheckCache(hierarchyhelp) or node.IsDirty(c4d.DIRTY_DATA)) : return node.GetCache(hierarchyhelp) if self.reference: if self.toggle: res = c4d.BaseObject(c4d.Ocube) else: res = c4d.BaseObject(c4d.Osphere) self.toggle = not self.toggle return res else: return None if __name__ == "__main__": path, file = os.path.split(__file__) bmp = bitmaps.BaseBitmap() bmp.InitWith(os.path.join(path, "res", "fhOdataTest.tif")) plugins.RegisterObjectPlugin(id = 1029736, str = "odatatest", g = fhOdataTestData, description = "odatatest", icon = bmp, info = c4d.OBJECT_GENERATOR)
-
On 27/04/2013 at 02:22, xxxxxxxx wrote:
Briljant, thank you very much!
It works as hoped.