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