How to get a variable from plugin.tag

On 16/03/2013 at 02:46, xxxxxxxx wrote:

It doesn't work with Python unfortunately. We do not have access to the NodeData of a plugin in
Python, or better say we can not get the NodeData from a BaseList2D object! It would be possible
with a bit of hacking, but it's not very "beautiful".

You could exchange information via a Python module or a c4dtools.library.Library class. I do
not recommend the first one. An example for the c4dtools Library to be put in your Python plugin
file:

  
#
# Python Plugin File
#
  
import c4d
import weakref
import c4dtools
  
class PluginTag(c4d.plugins.TagData) :
  
    op = None
    instances = []
  
    def Init(self, op) :
        self.instances.append(weakref.ref(self))
  
        self.list_ = []
        self.op = op
        return True
  
    def Free(self) :
        try:
            self.instances.remove(weakref.ref(self))
        except ValueError:
            pass
  
    # ...
  
class MyLibrary(c4dtools.library.Library) :
  
    class Meta:
        # Global unique identifier!
        name = 'my-super-duper-cool-library'
  
    def get_plugin_tags(self) :
        return PluginTag.instances[:]
  
#
# Python Tag (or just somewhere else than the plugin file)
#
  
import c4dtools
lib = c4dtools.load_library('my-super-duper-cool-library')
for data in lib.get_plugin_tags() :
    data = data() # dereference the weakref
    if not data:
        continue
  
    print data.list_

Note that this only works when you place the c4dtools module somewhere the Python Interpreter
can always find it, and not as a local distributed dependency as described in this article.

On 16/03/2013 at 03:15, xxxxxxxx wrote:

Hey Niklas,

thank you very much. I´ll try your lines.
But one other question. Is it easier/allowed to exchange information between NodeData(plugin.tag) and BaseData(command.tag)?

On 16/03/2013 at 03:24, xxxxxxxx wrote:

the most common approach would be messages for such a problem. both the sending

and the recieving class would implement a message method and therefore had to be 
derived from a c4d class which implements such a method. but i have never tried this
from a script (python-tag).

On 16/03/2013 at 03:24, xxxxxxxx wrote:

Hi rown,

yes it is allowed, but limited in Python. You can easily exchange data within C++ between the
plugin classes.

@Ferdinand:

You can not send a Python object via messages (from Python). But actually.. it's a good idea. This
would be possible to implement I think. Maybe they can add it for R15. :slightly_smiling_face:

On 16/03/2013 at 04:29, xxxxxxxx wrote:

i am not talking about sending the instance, but his data, some arrays or whatever.
and aside from that. the data contains pyobjects, not sure if i do understand pyobjects 
correctly, but aren't they meant to hold references to methods and such stuff too ?
never went down very far this rabbit hole, sending some variables always has been 
enough for me.

or i musunderstood this thread, i thought he has pluginclass a with member b. now he
wants to read b from somewhere only knowing the gelistnode instance associated with
his plugin.

On 16/03/2013 at 04:35, xxxxxxxx wrote:

Hi Ferdiand,

Holy Sh*t I really didn't know that was possible!

import c4d
  
MY_MSG = 5000140436
  
class Test(c4d.plugins.ObjectData) :
  
    def Message(self, op, msg, data) :
        if msg == MY_MSG:
            data.do_stuff()
        return True
  
class Foo(object) :
  
    def do_stuff(self) :
        print "Foo.do_stuff()"
  
def main() :
    op.Message(MY_MSG, Foo())

And you knew that? I always thought that was not possible (didn't try it out since now, though)!
That's so awesome! :joy:

On 16/03/2013 at 04:44, xxxxxxxx wrote:

Seriously, is that in the documentation?! I never read it anywhere! From several reasons and
thinkings I concluded it would not be possible. I see, I should just have tried it out!

Anyway, rown, something like this should work then:

MSG_GIMMELIST = 10000234 # Unique Identifier from the Plugincafe!
  
class PlgTAG(plugins.TagData) :
  
    list_ = []
  
    def Init(self, node) :
        return True
  
    def Message(self, node, type, data) :
        if type == MSG_GIMMELIST:
            data.value = self.list_
        return True
  
    def AnyFunctionToDefineList(self, ... ) :
        self.list_ =  ["Hello", 12.3, "Everybody"]
MSG_GIMMELIST = 10000234 # Unique Identifier from the Plugincafe!
  
class ValueBox(object) :
  
    def __init__(self, value=None) :
        super(ValueBox, self).__init__()
        self.value = value
  
def main() :
    tag = op.GetTag(c4d.Tplg)
    box = ValueBox()
    tag.Message(MSG_GIMMELIST, box)
    print box.value

Best,
-Niklas

On 16/03/2013 at 05:05, xxxxxxxx wrote:

IT IS UNBELIEVABLE!!!

Thank you both very much! Thanks Devil for letting Niklas know that and thanks Niklas for letting me know how it works.

Greetings
rown


On 16/03/2013 at 05:09, xxxxxxxx wrote:

My thanks go to Ferdinand as well, I never would've known that if he wouldn't have told me. :)

On 16/03/2013 at 06:35, xxxxxxxx wrote:

lol, you are welcome. and no i didn't know it exactly, but i assumed it. yannick showed here 
once how to unpack pyobject data from a message method, which led me to some reading 
about the pyobject class.