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
    • Recent
    • Tags
    • Users
    • Login

    Interaction tag as plugin

    Scheduled Pinned Locked Moved PYTHON Development
    14 Posts 0 Posters 1.2k 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 21/10/2015 at 06:32, xxxxxxxx wrote:

      Hi
      I have an Interaction tag acting as a point constraint plugin. I've placed the code in the draw method, and that works in the view port except for a slight delay when dragging. But it doesn't work when rendering to the PV. Is that because the draw method isn't called when rendering to the PV?

        
      import c4d   
      from c4d import gui   
      #The tag has a user data field (link) for a point selection tag.   
        
      def draw(bd) :   
          #Get the number of points from the object that belongs to the tag in the user data field   
          count = tag[c4d.ID_USERDATA,1].GetBaseSelect().GetCount()   
          #Get the object that the tag belongs to   
          pointObject = tag[c4d.ID_USERDATA,1].GetObject()   
        
          #Convert the tag's data to a BaseSelect so we can do something with them   
          PointS = tag[c4d.ID_USERDATA,1].GetBaseSelect()   
             
          #Points in the tag will have an enabled state value in our BS instance   
          pntArray = PointS.GetAll(tag[c4d.ID_USERDATA,1].GetObject().GetPointCount())   
        
          #Calculate the global position of point   
          newPos = pointObject.GetMg() * pointObject.GetPoint(pntArray.index(1))   
             
          #Set up the matrix components   
          off = newPos   
          v1 = c4d.Vector( op.GetMg().v1 )   
          v2 = c4d.Vector( op.GetMg().v2 )   
          v3 = c4d.Vector( op.GetMg().v3 )   
             
          #Build the Matrix   
          objMatrix = c4d.Matrix(off,v1,v2,v3)   
          #Set ops Matrix   
          op.SetMg(objMatrix)
      

      Am i supposed to use the message method instead? If so, what message should the plugin listen for? Or is there an other way of approaching this with out making a full plugin.

      Any help appreciated

      -b

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

        On 21/10/2015 at 06:38, xxxxxxxx wrote:

        Hi Bonsak,

        1. draw() is not called when rendering
        2. draw() is really only for drawing in the viewport, don't do any scene changes in it
        3. any reason you're not using a plain Python Tag?
        4. not sure, but if the Interaction Tag also supports a main() function, you should use that instead

        -N

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

          On 21/10/2015 at 06:53, xxxxxxxx wrote:

          I see. I was planning for some added functionality with selected/unselected states etc but i can use a python tag for now. Seemed convenient with the Interaction tag.
          Thanks for the help.

          -b

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

            On 22/10/2015 at 01:46, xxxxxxxx wrote:

            Hi Bonsak,

            I have a solution to this but it's not perfect. I've been using a python tag for the majority of my code, then throwing all of the data I need to draw into a global BaseContainer (or a stored object variable), then in the interaction tag, I use c4d.CallFunction to access it through a predefined function in the python tag. So essentially I'm only using the Interaction tag to draw stuff.

            It does have limited uses but it's a workflow that can be useful.

            Hope that helps,

            Adam

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

              On 22/10/2015 at 01:51, xxxxxxxx wrote:

              Thanks Adam. I'll definitely try that.

              -b

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

                On 27/10/2015 at 09:01, xxxxxxxx wrote:

                Originally posted by xxxxxxxx

                Hi Bonsak,

                I have a solution to this but it's not perfect. I've been using a python tag for the majority of my code, then throwing all of the data I need to draw into a global BaseContainer (or a stored object variable), then in the interaction tag, I use c4d.CallFunction to access it through a predefined function in the python tag. So essentially I'm only using the Interaction tag to draw stuff.

                Could you please post an example how you use the CallFunction.

                -Pim

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

                  On 27/10/2015 at 10:12, xxxxxxxx wrote:

                  Hi Pim,

                  This is an example of how I would move the data from a python tag to an interaction tag:

                  First the python tag:

                    
                  # Set up the function that is going to be called from the other python object
                  def GetMatrix() :
                      
                      if not matrix: return None
                      
                      bc = c4d.BaseContainer()
                      
                      bc.SetMatrix(0, matrix)
                      
                      return bc
                    
                  matrix = None
                    
                  def main() :
                      obj = op.GetObject()
                      
                      global matrix
                      #Assign the global variable with some data
                      matrix = obj.GetMg()
                    
                  

                  And then the Interaction tag:

                    
                  def draw(bd) :
                    
                      # The python object you want to call the function from
                      py_op = op[c4d.ID_USERDATA,1] 
                      
                      # Call the function from the python tag to get the BaseContainer
                      bc = c4d.CallFunction(py_op, "GetMatrix")
                      
                      #Get the matrix
                      matrix =  bc.GetMatrix(0)   
                      
                      #Do stuff!
                      print matrix
                    
                  
                  

                  Hope that's useful.

                  Thanks,

                  Adam

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

                    On 28/10/2015 at 05:56, xxxxxxxx wrote:

                    Thanks, very useful.
                    It seems like a very easy way to communicate between plugins!

                    I am only confused about py_op.
                    How / why does it point to the python object?

                    The manual is not very clear to me:
                    Parameters:|

                    • op  (BaseList2D[URL-REMOVED]) – The object to search the function within its script.

                    ---|---
                    _<_t_>_
                    -Pim


                    [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

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

                      On 28/10/2015 at 06:15, xxxxxxxx wrote:

                      The 'op' variable by default in the interaction tag refers to the object the tag is on and not the tag itself.

                      The interaction tag I was using was on a Null object. I set a UserData link box onto the Null and put the PythonTag into it as an easy way of referencing it.

                      Hence :

                      py_op = op[c4d.ID_USERDATA,1]
                      #op is the Null object
                      #ID_USERDATA,1 being the LinkBox with the PythonTag referenced to it.
                      

                      I guess I could have just used op.GetFirstTag() too, as the PythonTag was first on the Null object.

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

                        On 28/10/2015 at 09:04, xxxxxxxx wrote:

                        Ok, clear now.
                        If I want to communicate with another plugin, the op will be that plugin.

                        -Pim

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

                          On 28/10/2015 at 09:08, xxxxxxxx wrote:

                          I think that he CallFunction command might unfortunately be limited to certain objects, it looks like plugins are not included.

                          From the documentation:

                          "This works for both Python and C.O.F.F.E.E. scripting tags, effectors, XPresso nodes, Interaction tags and also for Python generators."

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

                            On 28/10/2015 at 09:21, xxxxxxxx wrote:

                            I agree,it is not very clear.
                            As I read it, it should also be possible for plugins.
                            A plugin is also an (scripting) object.

                            Perhaps Maxon can clarify?

                            -Pim

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

                              On 29/10/2015 at 10:35, xxxxxxxx wrote:

                              Hello everyone,

                              I'm sorry, but a Python plugin is not a scripting object. CallFunction() can not be used to communicate with a Python plugin.
                              CallFunction() only works for NodeData derived things, which already provide a scripting option (like Python tag, Interaction tag, Python Generator,...).

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

                                On 29/10/2015 at 12:33, xxxxxxxx wrote:

                                Thanks,that clarifies it for me.

                                -Pim

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