On 02/02/2017 at 14:26, xxxxxxxx wrote:
I'm trying to move userdata elements between groups, but it fails if the new parent group was created after the child element (the child element ends up on the top level). I'm guessing this is because elements are read in order and so when the specified parent group hasn't been read in it just punts.
Is there an elegant way to handle this?
The script below is a simplified example. When run, the GRP group ends up on the top level, but it should be under PARENT\SUB2 in the User Data tab. You can see the correct result if you Manage User Data and then click OK.
import c4d
from c4d import gui
#Welcome to the world of Python
def CreateUserDataGroup(obj, name, parentGroup=None, columns=None, shortname=None) :
if obj is None: return False
if shortname is None: shortname = name
bc = c4d.GetCustomDatatypeDefault(c4d.DTYPE_GROUP)
bc[c4d.DESC_NAME] = name
bc[c4d.DESC_SHORT_NAME] = shortname
bc[c4d.DESC_TITLEBAR] = 1
if parentGroup is not None:
bc[c4d.DESC_PARENTGROUP] = parentGroup
if columns is not None:
bc[c4d.DESC_LAYOUTGROUP] = True
bc[c4d.DESC_COLUMNS] = columns
return obj.AddUserData(bc)
def CreateUserDataFloat(obj, name, val=0, parentGroup=None, unit=c4d.DESC_UNIT_REAL) :
if obj is None: return False
bc = c4d.GetCustomDatatypeDefault(c4d.DTYPE_REAL)
bc[c4d.DESC_NAME] = name
bc[c4d.DESC_SHORT_NAME] = name
bc[c4d.DESC_DEFAULT] = val
bc[c4d.DESC_ANIMATE] = c4d.DESC_ANIMATE_ON
bc[c4d.DESC_UNIT] = unit
bc[c4d.DESC_CUSTOMGUI] = c4d.CUSTOMGUI_REALSLIDER
bc[c4d.DESC_MINSLIDER] = -500
bc[c4d.DESC_MAXSLIDER] = 500
bc[c4d.DESC_STEP] = 1
if parentGroup is not None:
bc[c4d.DESC_PARENTGROUP] = parentGroup
element = obj.AddUserData(bc)
obj[element] = val
return element
def main() :
print "*"*10
# Create the initial userdata definition
parentgroup = CreateUserDataGroup(op,"PARENT")
subgroup = CreateUserDataGroup(op,"SUB",parentgroup)
group = CreateUserDataGroup(op,"GRP",subgroup)
data = CreateUserDataFloat(op,"FLOAT",0,group)
# Print the current userdata container
ud = op.GetUserDataContainer()
for id, bc in ud:
print id, bc[c4d.DESC_NAME], bc[c4d.DESC_PARENTGROUP]
for i in range(0,id.GetDepth()) :
print "-- %s, %s, %s" % (id[i].id, id[i].dtype, id[i].creator)
if id == group:
groupdata = bc
c4d.EventAdd()
print "*"*10
# Simulate a later operation, moving subgroup to a new group
subgroup2 = CreateUserDataGroup(op,"SUB2",parentgroup)
groupdata[c4d.DESC_PARENTGROUP] = subgroup2
op.SetUserDataContainer(group,groupdata)
# Print the current userdata container
ud = op.GetUserDataContainer()
for id, bc in ud:
print id, bc[c4d.DESC_NAME], bc[c4d.DESC_PARENTGROUP]
for i in range(0,id.GetDepth()) :
print "-- %s, %s, %s" % (id[i].id, id[i].dtype, id[i].creator)
c4d.EventAdd()
if __name__=='__main__':
main()