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 get a variable from plugin.tag

    Scheduled Pinned Locked Moved PYTHON Development
    15 Posts 0 Posters 1.3k 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 16/03/2013 at 02:09, xxxxxxxx wrote:

      Hello spedler,

      thanks for reply. I know how to get my tag in python-tag and checking if its attached and so. The example is just an example.

      Originally posted by xxxxxxxx

      If it's an array (as you showed in your code) you'll have to make it available to other objects in some way.

      But thats what I want. I do not know anything about C++, so Ive to take a look what private means and getter/setter is.
      Is C++ -> public the same as Python -> global? If so, Im still not sure how to call the list/array from python tag.

      Thanks very much
      rown

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

        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.

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

          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)?

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

            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).

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

              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. 🙂

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

                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.

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

                  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! 😂

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

                    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

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

                      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


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

                        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. 🙂

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

                          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.

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