Interaction tag as plugin



  • 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



  • 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



  • 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



  • 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



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

    Thanks Adam. I'll definitely try that.

    -b



  • 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



  • 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



  • 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](file:///D:/sdk%20manuals/Python%20R16sdk%20manual/help/modules/c4d/C4DAtom/GeListNode/BaseList2D/index.html#c4d.BaseList2D)) – The object to search the function within its script.

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



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



  • 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



  • 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."



  • 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



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



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

    Thanks,that clarifies it for me.

    -Pim


Log in to reply