Update Layer Manager From Python Script Tag



  • On 17/11/2016 at 11:24, xxxxxxxx wrote:

    Hello Forum.

    I have a User Data bool checkbox set up in a rig.  I would like to SetLayerData() from a Python Script Tag if the checkbox is checked.  Here is the code:

    # This code is inside a Python Script Tag
    reset_layers = object_with_userdata[c4d.ID_USERDATA, 1]  # Bool
    if reset_layers:
        layer_root = doc.GetLayerObjectRoot()
        layer = layer_root.GetDown()
        layer.SetLayerData(doc, {'view': True})
        # layer.Message(c4d.MSG_CHANGE) # Does not work.
        # layer.Message(c4d.MSG_UPDATE) # Does not work.
        # c4d.EventAdd() # Works. Is this OK?
    object_with_userdata[c4d.ID_USERDATA, 1] = False
    

    This code works and the layer is updated, but the Layer Manager does not update to reflect the changes.
    If I execute c4d.EventAdd() the manager is updated.  
    Is it OK to call c4d.EvenAdd() inside a Python Scripting Tag?
    If not, what is the proper way to update the Layer Manager?

    If you have time...
    I assumed that EventAdd() would be called internally after a Python Tag was interpreted.  What actually happens?

    Thank you,

    Joe Buck



  • On 18/11/2016 at 01:33, xxxxxxxx wrote:

    Hello,

    can you tell us what exactly you are doing?

    The "main" function of a Python tag is executed every time when the current scene is evaluated. The purpose of the "main" function is to edit the host object, not to edit the scene. So in the "main" function you should not edit the layers and you should not call EventAdd() (which just would trigger another scene evaluation).

    On the other hand since R17.053 you can implement the "message" function in a Python tag. This "message" function receives messages when (user data) parameters on the tag are changed. In reaction to such an event you could edit the layers. If you do this you have to inform Cinema that such a change occurred with EventAdd().

    best wishes,
    Sebastian



  • On 18/11/2016 at 09:48, xxxxxxxx wrote:

    Hi Sebastian,

    I am trying to set layers with a Python Scripting Tag.

    Here is a link to a simple example:
    https://s3-us-west-1.amazonaws.com/jbplugincafeimageuploads/111816/plugin_cafe_python_tag_set_layer_objects.zip

    To use the example: 
    Select the null named Control.  
    Click on the User Data Checkbox named "Layer Set Up 1".
    The Layer named "Yellow" will now be Visible and Unlocked.
    Click on the User Data Checkbox named "Layer Set Up 2"
    The Layer named "Yellow" will now be Hidden and Locked.

    Here is the code in the Python Tag:

    import c4d
      
      
    def get_next_object(obj, **kwargs) :
        if obj is None:
            return None
        # using stop_obj will only check a branch of the hierarchy.
        # It will not check siblings below/above stop_obj
        # if stop_obj is None, all objects below the starting
        # object will be checked.  Objects
        # above start object will not be checked.
        if "stop_obj" in kwargs:
            stop_obj = kwargs['stop_obj']
        else:
            stop_obj = None
        if obj.GetDown() :
            return obj.GetDown()
        while not obj.GetNext() and obj.GetUp() :
            obj = obj.GetUp()
            # quit searching if recursed up to stop_obj.
            if obj == stop_obj:
                return None
        # do not get sibling below if stop_obj.
        if obj == stop_obj:
            return None
        obj = obj.GetNext()
        return obj
      
      
    UD_ID_LAYER_SETUP_1_BOOL = 1
    UD_ID_LAYER_SETUP_2_BOOL = 2
      
      
    def main() :
        control = op.GetObject()
        layer_set_up_1 = control[c4d.ID_USERDATA, UD_ID_LAYER_SETUP_1_BOOL]
        if layer_set_up_1:
            layer_object_root = doc.GetLayerObjectRoot()
            layer = layer_object_root.GetDown()
            while layer:
                if layer.GetName() == "Yellow":
                    layer.SetLayerData(doc, {'view': True, 'locked': False})
                layer = get_next_object(layer, stop_obj=layer_object_root)
            control[c4d.ID_USERDATA, UD_ID_LAYER_SETUP_1_BOOL] = False
            c4d.EventAdd()
        
        layer_set_up_2 = control[c4d.ID_USERDATA, UD_ID_LAYER_SETUP_2_BOOL]
        if layer_set_up_2:
            layer_object_root = doc.GetLayerObjectRoot()
            layer = layer_object_root.GetDown()
            while layer:
                if layer.GetName() == "Yellow":
                    layer.SetLayerData(doc, {'view': False, 'locked': True})
                layer = get_next_object(layer, stop_obj=layer_object_root)
            control[c4d.ID_USERDATA, UD_ID_LAYER_SETUP_2_BOOL] = False
            c4d.EventAdd()
    

    In the Python Tag I call c4d.EventAdd() to get the Layer Manager to update.  This does not seem right to me and I would like to know if this is a bad idea.

    Thank you,

    Joe Buck



  • On 19/11/2016 at 22:13, xxxxxxxx wrote:

    Hi Sebastian,

    I originally wanted to put User Data on an object, not a tag.  I will use your suggestion and put it on the Python Tag and override message().

    Thanks for your time and patience,

    Joe Buck


Log in to reply