Persisted data in Python Generator
-
On 22/01/2018 at 06:29, xxxxxxxx wrote:
With reference to an old Topic
Python Generator and Storing Variables [SOLVED]
(11881)
I need to persist some data over all frames and I wanted to use the suggested op[id] (where id is unique using a plugin id) The generator runs every frame and normal global variables are resetso initialising the variable dstore at the top = to the unique id if I write:
op[dstore] = 0 #Initialise
or op[dstore] += 1 # To Change, it works fine
(providing I don't change the type)but if I want to use a BaseContainer as in the example from the old Post:
myData = c4d.BaseContainer() myData[1] = "something" myData[2] = "something else" op[123456] = myData # something for data in op[123456]: print(data)
this works fine to initialise the data and you can read the data as op[123456][2] but you cannot change the data by op[123456][2] = "another' it doesn't error but does not update the value
So referencing another older post:
Initializing compositing-tag problem
(6282)
The only way I could update and persist the data properly was as follows:Above functions:
dstore = unique integer from plugin-idTo SetUp:
myData = c4d.BaseContainer()
myData[1000] = "something"
myData[2000] = 0
bc=op.GetDataInstance()
opData = bc.GetContainer(dstore)
bc.SetContainer(dstore, myData)To Change something in the structure:
bc=op.GetDataInstance()
opData = bc.GetContainer(dstore)
opData[2000] = 1
bc.SetContainer(dstore, opData)This persists and changes the data fine but I wonder if this is the best method? Ideally I would like to use a Dictionary but there is no SetDictionary method
Thanks
Dean -
On 23/01/2018 at 09:51, xxxxxxxx wrote:
Hi Dean,
welcome to the Plugin Café forums
There's nothing wrong with the described workflow, in the Python Generator you will have to resort to something like this.
To Change something in the structure:
bc=op.GetDataInstance()
opData = bc.GetContainer(dstore)
opData[2000] = 1
bc.SetContainer(dstore, opData)One hint on this code. Instead of using GetContainer() (which basically retrieves a copy of the BaseContainer) and then in the end using SetContainer(), you could do it just like you do with the object's BaseContainer and just get the instance of the BaseContainer via GetContainerInstance() and modify it directly, without the need to call SetContainer() in the end.
Finally the question on dictionaries. A BaseContainer can only store Cinema 4D types, a Python type like a dictionary can not be stored directly in a BaseContainer. On the other hand you can basically use a BaseContainer in a dictionary way, if you don't insist on having human readable keys. Or by having some kind of mapping function, which translates your human readable keys into numeric IDs.