this is what I would like to achieve:
This is what works so far:
Removing all userdata from object 'a':
for id, bc in aObj.GetUserDataContainer():
Copy userdata from object 'b' to 'a'
for id, bc in bObj.GetUserDataContainer():
But here comes the problem: after I copied one userdata element (type: vector) from object 'b' to object 'a', I can't then just remove all userdata from object 'a' and then copy another userdata element (type: float) from object 'c' to (the apparently not entirely cleaned) object 'a'. It seems to me that even after the remove function the previous userdata type is still cached. As a result to this, I get this error when I try to enter any vector data to this userdata element:
TypeError: __setitem__ expected c4d.Vector, not float
When I remove all userdata manually from object 'a' using the GUI it works, but using code like "RemoveUserData" seems to be not the same. In other words: how can I replace a userdata element from type A by another element from type B using python ?
I attached a file for testing:
3 null objects:
object 'b' has float userdata element
object 'c' has vector userdata element
object 'a' is the target object
Select the python script tag and select the userdata tab. You can run these 3 functions:
TypeError: __setitem__ expected float, not c4d.Vector
Really strange. Do I miss any additonal (update-) commands besides "RemoveUserData" in order to really remove any userdata and set new userdata types ?
Hi @m_adam, I also wish you a happy new year!
Thanks a lot for your workaround - this is working perfectly
Just one little correction: I guess, it's c4d.DESCFLAGS_SET_0 instead of c4d.DESCFLAGS_SET_NONE
My guess is (but I didn't check) that the user data entries on both objects, b and c, have the same ID. Therefore, you're copying the float value first, and then try to overwrite it with a vector. You probably have to check if a user data entry with that ID already exists, and then map the original user data id to a new one.
I guess there is a misunderstanding: I'm not only copying the userdata values but the complete structure between the objects. And I'm doing this after I've removed ALL userdata (not only the values) from the target object before ... so there should be no reason for any mismatching types. When I'm doing the removing part manually it's working - so the question is: why is using the python command "RemoveUserData" not the same like just deleting all userdata manually via the GUI ?
Again: the crucial step seems to be step 4). Removing all userdata structure manually via GUI results in no errors. But the python way via "RemoveUserData" caused the error in step 6)
Hi @ruckzuck , first of all, I wish you a happy new year!
Regarding your issue, I confirm there is an issue (I'm not sure exactly where it's located right now, either in our RemoveUserData function or either in the  operator). I will investigate this.
Anyway, use directly SetParameter make it works. I also did a quick rewrite of your code to clean it.
for id, bc in obj.GetUserDataContainer():
def copyUserData(src, dst):
for id, bc in src.GetUserDataContainer():
dst.SetParameter(id, src[id], c4d.DESCFLAGS_SET_NONE)
a = doc.SearchObject("a")
b = doc.SearchObject("b")
c = doc.SearchObject("c")
if not a or not b or not c: return
# Execute main()
If you have any questions left, please let me know.
No in R20 pretty all symbols were migrated from _0 to _NONE, for compatibility reason in python, _0 keep working as before but should be considered as deprecated.
A note in the documentation will be added and all symbols will be updated for the R20 SP2 documentation
Ah ok, good to know, thanks for clarifying this - I've tested this in R19 ... but I forgot to mention that, sorry.
Seems I also forget to mention but please use About Tags and Tagging like so you can mark a specific version.