Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Update Layer Manager From Python Script Tag

    Scheduled Pinned Locked Moved PYTHON Development
    4 Posts 0 Posters 354 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • First post
              Last post