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

    How to delete obj in the environment from a button in userdata

    Cinema 4D SDK
    r20 python
    2
    4
    714
    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.
    • JH23J
      JH23
      last edited by m_adam

      Can someone help me? I would like to be able to activate a button from userdata, and this delete an object or layer, it would help me a lot if they solve my doubt

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hi,

        welcome to the forum and community! And thank you for tagging your posting! I only moved your posting into the correct forum.

        Your question is a bit broad, so I picked some conditions under which to answer it. First of all I assume here that you are in the environment of one of the embedded Python objects, e.g., a Python generator. In case you are not, and in some form of NodeData plugin, the example below will translate almost directly.

        In principle you have to listen to the message send to the node, in case of a Python Generator object or a Python Programming tag with the message() function, in case of a NodeData plugin with your implementation of the NodeData.Message() method. Then you have to sort out if the message is of type MSG_DESCRIPTION_COMMAND and sort out the DescId of the sender. You will find a scene file and a code example below.

        I hope this helps and cheers,
        Ferdinand

        The file:
        delete_first_object.c4d

        The code:

        """ Example for listening for button clicks in a node.
        
        As discussed in:
            https://developers.maxon.net/forum/topic/13251
        """
        
        import c4d
        
        def main():
            """
            """
            pass
        
        def message(mid, data):
            """Retrieves messages sent to the node.
        
            Messages are used in Cinema 4D to convey event-like information. In this
            case we are listening for the buttons. The setup assumes there to be a 
            button with the user data id 1.
        
            Args:
                mid (int): The message id.
                data (Any): The message data.
        
            Returns:
                Any: Depends on the message type.
            """
            # Test if this is a description command message, i.e. a message sent by
            # one of our interface buttons.
            if mid is c4d.MSG_DESCRIPTION_COMMAND:
                # Interface elements are identified in Cinema with something called
                # DescId which is basically just a collection of IDs to identify
                # attributes of a node. DescId are organized in up to three 
                # DescLevels. The relative position of an object is for example 
                # identified by this DescId:
                # 
                #   c4d.DescId(id1=c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION))
                # 
                # Just the x component of that vector is represented like this:
                # 
                #   c4d.DescId(id1=c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION),
                #              id2=c4d.DescLevel(c4d.VECTOR_X)) 
                # 
                # So we have two level in this id, a first one that indicates it is
                # part of the relative position parameter and a second one which 
                # specifies that we only want to address the x-component of that 
                # vector.
                # 
                # For user data the organization is important, because all user data
                # in the parameter name space of an object lives under the first
                # DescLevel of ID_USERDATA (or 700 as an integer). The second 
                # DescLevel is then the user data ID like seen in the user data 
                # manger. To access the x-component of a vector that is an user data
                # element, we can use the third DescLevel, i.e., something like
                # (c4d.ID_USERDATA, 1, c4d.VECTOR_X) when the first user data element
                # is a vector.
        
                # In case of a MSG_DESCRIPTION_COMMAND message the DescID of the 
                # parameter that raised that message, in this case the button which
                # has been pressed by the user, is being sent with the message data
                # under the key "id".
                if not isinstance(data, dict) or "id" not in data:
                    raise RuntimeError("Malformed message data.")
                senderDescId = data["id"]
        
                # Now we have just to check if this message has actually been sent
                # by the user data button with the ID 1.
                if senderDescId[0].id == c4d.ID_USERDATA and senderDescId[1].id == 1:
                    print ("User data button with the id 1 has been pressed.")
                    # Get the first object in the scene and delete it.
                    node = doc.GetFirstObject()
                    # If either the first node is None (which should not happen, 
                    # because at least the node executing this code has to be in the 
                    # scene) or the first node is the python generator, then bail.
                    # The second part is of course optional, but we probably do not
                    # want to delete ourselves. It is important here to compare for
                    # equality and not for identity due to how Cinema handles nodes
                    # (i.e., node == op and not node is op, the latter will always be
                    # False).
                    if node is None or node == op:
                        return True
        
                    # Create an undo so the user can revert the action.
                    doc.StartUndo()
                    doc.AddUndo(c4d.UNDOTYPE_DELETE, node, )
                    # Delete the node, including its children.
                    node.Remove()
                    # Update Cinema 4D.
                    doc.EndUndo()
                    c4d.EventAdd()
        
            return True
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • JH23J
          JH23
          last edited by JH23

          This post is deleted!
          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by ferdinand

            Hello @JH23,

            without any further feedback or questions, we will consider this topic as solved by Wednesday and flag it accordingly.

            Thank you for your understanding,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

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