On 21/03/2013 at 16:51, xxxxxxxx wrote:
During the process of porting a C++ plugin to Python I stumbled upon something REALLY wacky.
In C++ we can write a plugin that consists of a Gedialog plugin and a TagData plugin.
Then we can get the Tag plugin's class member variables from within the GeDialog code and use it.
Upon doing this same thing in Python. It seemed to mostly work the same way as C++...Except in the case of lists (arrays) for some strange reason.
If I add a list as a class member of the tag. Then change that list via the GeDialog plugin. When I make a new tag on another object. That list's values get carried over to that new tag!!?
In other words. The class member list in my tags are not unique ( per tag ) as they are supposed to be.
Other types of variables don't do this... Only lists.
Every time a new tag is created. Other types of class members are unique as expected. But not when it comes to lists.
Here's an example of a GeDialog plugin that sets and gets the class members on a tag plugin.
import c4d,sys,os
from c4d import plugins, utils, bitmaps, gui, documents
TAG_PLUGIN_ID = 1000008 # THIS id IS FOR TESTING PUPOSES ONLY!!!
DIALOG_PLUGIN_ID =1000009 # THIS id IS FOR TESTING PUPOSES ONLY!!!
################################################################
###################### Tag Plugin ##############################
class StorageTag(plugins.TagData) :
tagListData = ["Nothing"] #A list that will be changed by the dialog plugin
tagVariableValue = "Nothing" #A variable that will be changed by the dialog plugin
def Init(self, tag) :
data = tag.GetDataInstance()
return True
def Execute(self, tag, doc, op, bt, priority, flags) :
return True
if __name__ == "__main__":
path, fn = os.path.split(__file__)
bmp = bitmaps.BaseBitmap()
bmp.InitWith(os.path.join(path, "res/icons/", "myicon.png"))
plugins.RegisterTagPlugin(TAG_PLUGIN_ID, "PyStorageTag",c4d.TAG_VISIBLE + c4d.TAG_EXPRESSION,StorageTag,"MyTag_dec", bmp)
################################################################
################### Dialog Plugin ##############################
#enums
BUTTON = 1001
BUTTON2= 1002
class MyDialog_Gui(gui.GeDialog) :
def CreateLayout(self) :
self.SetTitle("Dialog")
self.AddButton(BUTTON, c4d.BFH_CENTER, 60, 10, name="Press Me")
self.AddButton(BUTTON2, c4d.BFH_CENTER, 80, 10, name="Get Tag value")
return True
def InitValues(self) :
return True
def Command(self, id, msg) :
doc = documents.GetActiveDocument()
activeObj = doc.GetActiveObject() #The obect holding the tag
if not activeObj: return False
tag = activeObj.GetTag(TAG_PLUGIN_ID) #Get the tag on the object
if not tag: return False
st = tag.GetNodeData() #Get The tag's data (including the class members)
if id == BUTTON:
st.tagVariableValue = "variable Value Changed" #Change the value of the tag's member variable
st.tagListData[0] = "List Value Changed" #Change the value of the tag's member list
if id == BUTTON2:
print st.tagVariableValue #Get the current values of the tag's members
print st.tagListData[0]
c4d.EventAdd()
return True
class myDialog_Main(plugins.CommandData) :
dialog = None
def Execute(self, doc) :
if self.dialog is None:
self.dialog = MyDialog_Gui()
return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=DIALOG_PLUGIN_ID, defaultw=0, defaulth=0, xpos=-1, ypos=-1)
def RestoreLayout(self, sec_ref) :
if self.dialog is None:
self.dialog = MyDialog_Gui()
return self.dialog.Restore(pluginid=DIALOG_PLUGIN_ID, secret=sec_ref)
if __name__ == "__main__":
path, fn = os.path.split(__file__)
bmp = bitmaps.BaseBitmap()
bmp.InitWith(os.path.join(path, "res/icons/", "None"))
plugins.RegisterCommandPlugin(DIALOG_PLUGIN_ID, "My Dialog",0,None,"", myDialog_Main())
This is really wacky. And doesn't seem to happen in C++ plugins.
How do I stop lists from spilling over into other instances of the tag like this?
Is this a bug?
-ScottA