SOLVED Syncing Object Property Update in ObjectData

Hello,
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:
alt text

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?

Thank you!

Hi,

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
        self.SetOptimizeCache(True)

    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
                    0.5)
            # To avoid nasty chain reactions when Message is not called from the
            # main thread, which should not happen normally.
            if not c4d.threading.GeIsMainThread():
                return True
            # 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)
        return True

    def GetVirtualObjects(self, op, hierarchyhelp):
        """
        """
        return self.CreateMyObject(op, self._cached_value or 1.)

Cheers,
zipit

Hi,

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
        self.SetOptimizeCache(True)

    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
                    0.5)
            # To avoid nasty chain reactions when Message is not called from the
            # main thread, which should not happen normally.
            if not c4d.threading.GeIsMainThread():
                return True
            # 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)
        return True

    def GetVirtualObjects(self, op, hierarchyhelp):
        """
        """
        return self.CreateMyObject(op, self._cached_value or 1.)

Cheers,
zipit

@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??!