Adding items to a LONG/CYCLE description container.
-
Hi !
I'm finishing developing my first python tag plugin but there's one thing that I can't figure out how to do.... I've read the documentation and searched for some examples, but no success
Basically I want to add a list of string to the File
LONG CYCLE
container.
This is the part on my
.py
file where I get the strings:datafilename = tag.GetDataInstance() path = datafilename.GetFilename(STRINGTEST) extensions = ["exr","hdr","jpg","png"] c = 0 files = os.listdir(path) for names in files: ext = names.rsplit(".",1) if ext[1] in extensions: c = c + 1 lista = c lista = str(c)+';'+path+'\\'+names print lista
This is the part of my
.res
file where the cointainer is:FILENAME STRINGTEST {DIRECTORY;} LONG TESTSCALE { CYCLE { } }
I think I would be able to do this with
GetDDescription
, but I have no idea and haven't found examples in how to do itDoes anyone know how to do it ?
-
Hi @FlavioDiniz, first of all, welcome in the plugincafe community!
Don't worry, since it's your first topic, I've set up your topic correctly. But please for your next topics, use the Q&A functionnaly, make sure to also read How to Post Questions.
With that's said you can find the manual about SetDParameter in the C++ docs which will be trigger each time a user changes a value in the description of your tag. And also the C++ manual about GetDDescription.
Here a quick example of the implementation in pythonextensions = ["exr","hdr","jpg","png"] # Called by C4D when loading description def GetDDescription(self, node, description, flags): data = node.GetDataInstance() if data is None: return False # Load the description if not description.LoadDescription(node.GetType()): return False # If there is no description for c4d.TESTSCALE, we create it. Otherwise we override it and set DESC_CYCLE with our extensions list. singleID = description.GetSingleDescID() paramID = c4d.DescID(c4d.TESTSCALE) if singleID is None or paramID.IsPartOf(singleID)[0]: bcParam = description.GetParameterI(c4d.TESTSCALE) items = c4d.BaseContainer() for i, extension in enumerate(self.extensions): items.SetString(i, extension) bcParam[c4d.DESC_CYCLE] = items return (True, flags | c4d.DESCFLAGS_DESC_LOADED) # Called when a parameter is Set def SetDParameter(self, node, id, t_data, flags): if not node: return # called when the filename is changed. We add the path to our list and we return c4d.DESCFLAGS_PARAM_SET to inform c4d the paramaters is just sets if id[0].id == c4d.STRINGTEST: self.extensions.append(t_data) return (True, flags | c4d.DESCFLAGS_PARAM_SET) return False
If you have any questions, please let me know!
Cheers,
Maxime. -
hi @m_adam, thanks a lot for your answer!
I spent two days trying to implement the function in my code, but no success again
I think the problem now is more related to python than the C4D SDK,i'm not that experienced on it...The error i'm getting is:
AttributeError: 'testplugin' object has no attribute 'hdrs'
hdrs
is the list of strings (file paths), but seems that this list cannot be read by the GetDDescription function....
I've tried putting it as aglobal
variable, also putting undertestplugin class
, underExecute
, etc..
Tried putting theGetDDescription
andSetDParameter
as a inner function ofExecute
(I think this is wrong.. didn't give me errors, but updating the cycle doesn't work too haha).Here's the structure of my plugin, I removed some irrelevant parts so we can focus better where the error is...
Do you think the structure is correct or am I missing something ?the
.res
file is the same as in my first post.import c4d import os import sys from c4d import gui, plugins, bitmaps PLUGIN_ID = 1000001 TESTSCALE = 1001 STRINGTEST = 1003 class testplugin(plugins.TagData): def Init(self, node): tag = node data = tag.GetDataInstance() FDWhite = c4d.Vector(1,1,1) data.SetBool(FDENABLEBG, True) data.SetInt32(FDSATURATION, 100) data.SetVector(FDTINT, FDWhite) data.SetInt32(FDSAMPLES, 64) def Execute(self, tag, doc, op, bt, priority, flags): datafilename = tag.GetDataInstance() #FD Folder path path = datafilename.GetFilename(STRINGTEST) extensions = ["exr","hdr"] hdrs = [] if path != "": files = os.listdir(path) for names in files: ext = names.rsplit(".",1) if ext[1] in extensions: hdrs.append(path+'\\'+names) return c4d.EXECUTIONRESULT_OK def GetDDescription(self, node, description, flags): # Called by C4D when loading description data2 = node.GetDataInstance() if data2 is None: return False if not description.LoadDescription(node.GetType()): # Load the description return False singleID = description.GetSingleDescID() paramID = c4d.DescID(c4d.TESTSCALE) if singleID is None or paramID.IsPartOf(singleID)[0]: bcParam = description.GetParameterI(c4d.TESTSCALE) items = c4d.BaseContainer() for i, hdrs in enumerate(self.hdrs): items.SetString(i, hdrs) bcParam[c4d.DESC_CYCLE] = items return (True, flags | c4d.DESCFLAGS_DESC_LOADED) def SetDParameter(self, node, id, t_data, flags): # Called when a parameter is Set if not node: return if id[0].id == c4d.STRINGTEST: self.hdrs.append(t_data) return (True, flags | c4d.DESCFLAGS_PARAM_SET) return False if __name__ == "__main__": bmp = bitmaps.BaseBitmap() dir, file = os.path.split(__file__) bitmapfile = os.path.join(dir, "res", "icon.tif") result = bmp.InitWith(bitmapfile) plugins.RegisterTagPlugin(id=PLUGIN_ID, str="FD HDR", info=c4d.TAG_EXPRESSION|c4d.TAG_VISIBLE, g=testplugin, description="testplugin", icon=bmp)
thanks again
-
You have to declare
hdrs
as a member variable. See 9.3.5: https://docs.python.org/2/tutorial/classes.html