Getting the object of a tag

On 25/05/2014 at 03:52, xxxxxxxx wrote:

I have a tag plugin and assign that tag plugin to an object.
In the init part of the tag plugin I am using op = node.GetObject() to get the attached object of the tag
Except, I always get None?

class RESBUT(plugins.TagData) :
    def Init(self, node) :
        op = node.GetObject()
        print "Init, node, op: ", node, op
        return True
    def Execute(self, tag, doc, op, bt, priority, flags) :
        return True
if __name__ == "__main__":
    bmp = bitmaps.BaseBitmap()
    dir, file = os.path.split(__file__) 
    bitmapfile = os.path.join(dir, "res", "Icon.tif")
    #print bitmapfile
    result = bmp.InitWith(bitmapfile)
    if not result:
        print "Error loading bitmap!"
    plugins.RegisterTagPlugin(id=PLUGIN_ID, str="Explosion v02", info=c4d.TAG_VISIBLE, g=RESBUT, description="resbut",  icon=bmp)

On 25/05/2014 at 08:35, xxxxxxxx wrote:

I've run into this kind of thing a lot.
What generally happens is the code is trying to grab an object that C4D has not finished creating, or parsing yet.

Because C4D takes so long (relatively speaking)  to find or create objects. I've gotten into the habit of using the Message() method for this when I can.
Using:  if( type == MSG_MENUPREPARE). That gives C4D as much time as it needs to find the object or tag I'm looking for safely without crashing.

It seems weird to me too that it can't find the object the tag is on in the init() function.
But C4D seems to be running that Init() code before it finishes parsing the objects in the scene.


On 26/05/2014 at 04:12, xxxxxxxx wrote:

Yes, it seems that when I attach my plugin tag to the object (dragging it onto the object).
The init is started before the tag is attached internally to the object.

I can do it in the execute part, but then I need some global variables to set / check status.
I'll try a little delay.


On 26/05/2014 at 04:20, xxxxxxxx wrote:

print node.GetObject() did not help. It still returns None!

On 26/05/2014 at 10:19, xxxxxxxx wrote:

Yeah. I went through all of that same stuff too.
Trying to use timers and whatnot to give C4D time to grab the object.
But in the end. The only 100% safe way I found to do it was by using the Message() method.
I don't think you'll find a better(safer) way to do it.

If you want to use the Init() method for setting a value.
Then go ahead and set the value there. But apply it to the tag or object inside of the Message() method.
Based on my experiences doing the same thing. That's the only 100% safe to make it work without a risk of crashing.


On 26/05/2014 at 14:59, xxxxxxxx wrote:

It's not "time" that Cinema 4D needs to "find" the object. The Tag is simply
not attached to the object when it gets initialized. Init() is called within
BaseTag::Alloc(), and that is what Cinema uses to create the tag. It can
add the Tag to the Object only after that function has finished.

So, it's a simple matter of execution order. You could sleep for bazillion
hours and Cinema would still not have the Tag attached to the Object,
as BaseObject::Alloc() has still not returned (so, by calling time.sleep(),
you're blocking the BaseObject::Alloc() call).

MSG_MENUPREPARE is a good place to make things like that.


On 27/05/2014 at 02:28, xxxxxxxx wrote:

"MSG_MENUPREPARE is a good place to make things like that."
Ok clear, but when in Execute, getting the object is not an issue.
obj = node.GetObject().

On 28/05/2014 at 02:52, xxxxxxxx wrote:

Of course it is not an issue. The Tag is attached at the time the its Execute() method is called.