Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
If I add a string field with AddUserData. And then I delete that string field with DeleteUserData. And then try to add a float field with AddUser Data: I get TypeError: setitem expected str, not float And if I try to get the value before EventAdd, I get the old, deleted value
Anyone know any workarounds? Like how to flush the memory of the user data?
Hi,
Even if a user data parameter is removed its data is still stored. And when [] operator is used, the Python API layer checks the type of a parameter before setting its data. The solution is to use del() passing the parameter data to clear its type and value. Then the parameter can be set any data.
del()
Here is how I modified the script you posted:
import c4d def AddUserData(obj, dtype, name): if obj is None: return # Retrieves default user data container for the passed type bc = c4d.GetCustomDataTypeDefault(dtype) bc[c4d.DESC_NAME] = name # Adds the user data element = obj.AddUserData(bc) # Returns the user data description ID return element def main(): # Searches for 'Cube' object cube = doc.SearchObject('Cube') if cube is None: return # Adds string user data dataID = AddUserData(cube, c4d.DTYPE_STRING, "String") cube[dataID] = 'bob' # Removes user data cube.RemoveUserData(dataID) # Clears user data type and value del(cube[dataID]) # Adds float user data dataID = AddUserData(cube, c4d.DTYPE_REAL, "Float") cube[dataID] = 22.2 # Updates Cinema c4d.EventAdd() if __name__=='__main__': main()
Note it's recommended to use main() like in the default script. Also when Cinema 4D runs scripts doc is the active document (op is the active object).
Here's a simple test to run in the script editor: Add a Cube to the scene.
import c4d current_doc = c4d.documents.GetActiveDocument() cube = current_doc.SearchObject('Cube') def AddStringDataType(obj): if obj is None: return bc = c4d.GetCustomDataTypeDefault(c4d.DTYPE_STRING) bc[c4d.DESC_NAME] = "String" element = obj.AddUserData(bc) obj[element] = 'bob' c4d.EventAdd() def AddFloatDataType(obj): if obj is None: return bc = c4d.GetCustomDataTypeDefault(c4d.DTYPE_REAL) bc[c4d.DESC_NAME] = "Float" element = obj.AddUserData(bc) obj[element] = 22.2 c4d.EventAdd() AddStringDataType(cube) cube.RemoveUserData(1) AddFloatDataType(cube)
This worked. Thank you.