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


Log in to reply