Automatically add tags at last position on creation

by .

Usually, when the user attaches a new tag to an object using the “Tags” menu in the Object Manager, the new tag is always added as first element to the object’s tag list.

For some tags, however, it would make sense to rather add them to the end of the object’s tag list. Especially if those tags should ‘layer’ their effects on top of each other (e.g. like multiple texture tags).

If you want your tag to be added to the end of the tag list automatically when it is being created, this article will tell you how.

Approach

Override your TagData’s Message function and catch the message type MSG_MENUPREPARE.

For that message type, you simply iterate over all existing tags (if there are any), remove the tag from the object it has just been attached to, and re-insert it after the last tag.

C++

MyTagData::Message(GeListNode* node, LONG type, void* data);
{
  if (type == MSG_MENUPREPARE)
  {
    // Get my own tag
    BaseTag *me = (BaseTag*)node;
    if (!me) return false;

    // Get the object
    BaseObject *op = me->GetObject();
    if (!op) return false;

    // Find the last tag
    BaseTag* last = op->GetFirstTag();
    if (last)
    {
      // Iterate over tags to find the last one
      for (; ; )
      {
        if (!last->GetNext())
          break;
        last = last->GetNext();
      }

      // Remove tag from the 1st position
      me->Remove();

      // Re-insert tag after last tag
      op->InsertTag(me, last);
    }
  }

  return SUPER::Message(node, type, data);
}

Python

def Message(self, node, type, data):
    if type == c4d.MSG_MENUPREPARE:
        # Get the object
        op = me.GetObject()
        if not op:
            return False

        # Find the last tag
        last = op.GetFirstTag()
        if last:
            # Iterate over tags to find the last one
            while True:
                if not last.GetNext():
                    break
                last = last.GetNext()

            # Remove tag from the 1st position
            me.Remove()

            # Re-insert tag after last tag
            op.InsertTag(me, last)

    return TagData.Message(node, type, data)
Advertisements