I am trying to sync ObjectData parameters through XPresso, but I cannot because my Object Properties aren't being updated at the same time. To demonstrate what I mean better, I came up with a Demo project. Here is a screen capture of the result:
In this screen capture, the planes' width & height are being set with XPresso. The blue plane is using the Object's Size Percentage which is in sync with the object. I included this plane to show that it is not an issue of the XPresso tag's priority. The red plane's size is using a value that is calculated based on the Size Percentage in my ObjectData.GetVirtualObjects override. I have tried the calculation at different points of the ObjectData (e.g. the init function, before/after the MSG_UPDATE Message, etc.), but I'm still experiencing the lag.
Here is an archive of my Demo ObjectData plugin and my scene file.
How can I make a calculation based on one parameter and update the Object Properties so that it stays in sync?
I do not mean to be rude, but I would really ask for putting up code in your postings rather than just images and drop-box links.
About your problem. I am not 100% sure what exactly you are trying to do, specifically the hard coded size attribute, the str that is actually an int and more is weirding me out. But given that I do not completely misunderstand your problem, this should fix it:
def __init__(self, *args):
# Not neccessary.
# super(DemoObject, self).__init__(*args)
self._cached_value = None
def Message(self, node, mid, data):
# When a parameter has been changed.
if mid == c4d.MSG_DESCRIPTION_POSTSETPARAMETER:
perc = (node[c4d.DEMOOBJ_SIZE_PERCENTAGE]
if node[c4d.DEMOOBJ_SIZE_PERCENTAGE] is not None else
# To avoid nasty chain reactions when Message is not called from the
# main thread, which should not happen normally.
if not c4d.threading.GeIsMainThread():
# When our percentage has changed, we have to safeguard our modification
# like that to avoid chain reactions. The proper message to do all this would
# actually be MSG_DESCRIPTION_VALIDATE, but this did not work out for
# me, not quite sure why.
if perc != self._cached_value:
self._cached_value = perc
data = node.GetDataInstance()
data[c4d.DEMOOBJ_WIDTH] = str(self.size * float(perc) * 2.0)
def GetVirtualObjects(self, op, hierarchyhelp):
return self.CreateMyObject(op, self._cached_value or 1.)
@zipit I'll post code with my scenes/screenshots in the future.
Setting the value in MSG_DESCRIPTION_POSTSETPARAMETER fixed my issue! Wow, how do you know all of this stuff??!