hello,
You create your UI dynamically but still use it to retrieves data. You should simply separate both.
The problem here is that Message()
is called before Main()
(nothing you can changed)
In the Message()
function you can check the id == MSG_DESCRIPTION_POSTSETPARAMETER, you can retrieves the descid in the data attached.
By checking the descid you can update only if the cycles are changed. (not the button)
Your Main()
can be "empty". I picked everything that was in Main()
and copy/paste in LaunchUpdate()
You should split that function in several parts.
In the random function I can now call LaunchUpdate()
to update the UI and use it to retrieves the data. (but as I said you should separate both)
This now works but LaunchUpdate()
is executed too much times. It would need more work to split that function in several parts.
This look more like a design issue than a Cinema4D issue.
Let me know if i'm not clear.
import c4d
from c4d import gui
from c4d import documents
import random
from random import randint
class bcSettings():
def Group(self,basecontainerVar,groupContainerVar,columns=1,parentGroupState=False,parentGroupId=0):
return {'Base container': basecontainerVar, 'Group container': groupContainerVar,'Columns': columns,'Subgroup': parentGroupState,'Parent group id': parentGroupId}
def CycleObj(self,basecontainerVar,groupContainerVar,parentGroupId=0,hide=True):
return {'Base container': basecontainerVar, 'Group container': groupContainerVar,'Parent group id': parentGroupId,'hideState': hide}
def CycleTex(self,basecontainerVar,groupContainerVar,effect,shader,parentGroupId=0):
return {'Base container': basecontainerVar, 'Group container': groupContainerVar,'effect': effect,'shader': shader,'Parent group id': parentGroupId}
def RandomButton (self,basecontainerVar,groupContainerVar,parentGroupId=0):
return {'Base container': basecontainerVar, 'Group container': groupContainerVar,'Parent group id': parentGroupId}
def BaseContainerVariable(index,typeName): #it's list func for checking and adding to list a new varaibale instead use one unique variable
if (len(index) == 0):
index.append(typeName + str(1))
else:
index.append(typeName + str(len(index) + 1))
return index
class base_controllers(object):
def __init__(self,userdataGroup,parentObject=None):
self.userdataGroup = userdataGroup
self.parentObject = parentObject
def Group(self,config,title,userDataId):
BaseContainerVariable(config['Base container'],'BaseContainerId')
CountCheckingBC = 0
#check if list is null and add new varabe to list
if (len(config['Base container']) > 0):
CountCheckingBC = len(config['Base container']) - 1
config['Base container'][CountCheckingBC] = title + 'BaseContainer'
config['Base container'][CountCheckingBC] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_GROUP)
else:
config['Base container'][0] = title + 'BaseContainer'
config['Base container'][0] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_GROUP)
#continue creating userdata
config['Base container'][CountCheckingBC].SetString(c4d.DESC_NAME, title)
config['Base container'][CountCheckingBC].SetString(c4d.DESC_SHORT_NAME, title)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_COLUMNS, config['Columns'])
if (config['Subgroup'] == True and config['Parent group id'] > 0 ): #check whether userdata should have a parent group
config['Base container'][CountCheckingBC].SetData(c4d.DESC_PARENTGROUP, c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA), c4d.DescLevel(config['Parent group id'], c4d.DTYPE_GROUP, 0)))
BaseContainerVariable(config['Group container'],'GroupContainerId')
CountCheckingCont = 0
#check if list is null and add new varabe to list
if (len(config['Group container']) > 0):
CountCheckingCont = len(config['Group container']) - 1
config['Group container'][CountCheckingCont] = c4d.BaseContainer()
config['Base container'][CountCheckingBC].SetContainer(c4d.DESC_CYCLE, config['Group container'][CountCheckingCont])
self.userdataGroup.SetUserDataContainer([c4d.ID_USERDATA, userDataId], config['Base container'][CountCheckingBC])
def CycleObj(self,config,title,userDataId):
BaseContainerVariable(config['Base container'],'BaseContainerId')
CountCheckingBC = 0
#check if list is null and add new varabe to list
if (len(config['Base container']) > 0):
CountCheckingBC = len(config['Base container']) - 1
config['Base container'][CountCheckingBC] = title + 'BaseContainer'
config['Base container'][CountCheckingBC] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_LONG)
else:
config['Base container'][0] = title + 'BaseContainer'
config['Base container'][0] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_LONG)
#continue creating userdata
limit = len(self.parentObject.GetChildren())
config['Base container'][CountCheckingBC].SetString(c4d.DESC_NAME, title)
config['Base container'][CountCheckingBC].SetString(c4d.DESC_SHORT_NAME, title)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_CUSTOMGUI, c4d.CUSTOMGUI_CYCLE)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_MIN, 0)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_MAX, limit-1)
config['Base container'][CountCheckingBC].SetData(c4d.DESC_PARENTGROUP, c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA), c4d.DescLevel(config['Parent group id'], c4d.DTYPE_GROUP, 0)))
BaseContainerVariable(config['Group container'],'GroupContainerId')
CountCheckingCont = 0
if (len(config['Base container']) > 0):
CountCheckingCont = len(config['Group container']) - 1
config['Group container'][CountCheckingCont] = c4d.BaseContainer()
for indexLoop in range(0, limit):#filling userdata container with object names
config['Group container'][CountCheckingCont].SetString(indexLoop, self.parentObject.GetChildren()[indexLoop].GetName())
config['Base container'][CountCheckingBC].SetContainer(c4d.DESC_CYCLE, config['Group container'][CountCheckingCont])
self.userdataGroup.SetUserDataContainer([c4d.ID_USERDATA, userDataId], config['Base container'][CountCheckingBC])
if (config['hideState'] == True): #hide all objects besides chosen
for indexObjectHide in range (0, limit):
if (indexObjectHide == self.userdataGroup[c4d.ID_USERDATA,userDataId]):
self.parentObject.GetChildren()[indexObjectHide].SetEditorMode(2)
self.parentObject.GetChildren()[indexObjectHide].SetRenderMode(2)
else:
self.parentObject.GetChildren()[indexObjectHide].SetEditorMode(1)
self.parentObject.GetChildren()[indexObjectHide].SetRenderMode(1)
def CycleTex(self,config,title,userDataId):
layer_list = []
temp_list_var = config['shader'].GetFirstLayer()
layer_list.append(temp_list_var)
while temp_list_var:# get layers
if temp_list_var.GetNext() is not None:
layer_list.append(temp_list_var.GetNext())
temp_list_var = temp_list_var.GetNext()
else:
break
count_texture = len(layer_list)
BaseContainerVariable(config['Base container'],'BaseContainerId')
CountCheckingBC = 0
if (len(config['Base container']) > 0):
CountCheckingBC = len(config['Base container']) - 1
config['Base container'][CountCheckingBC] = title + 'BaseContainer'
config['Base container'][CountCheckingBC] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_LONG)
else:
config['Base container'][0] = title + 'BaseContainer'
config['Base container'][0] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_LONG)
config['Base container'][CountCheckingBC].SetString(c4d.DESC_NAME, title)
config['Base container'][CountCheckingBC].SetString(c4d.DESC_SHORT_NAME, title)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_CUSTOMGUI, c4d.CUSTOMGUI_CYCLE)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_MIN, 0)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_MAX, count_texture-1)
config['Base container'][CountCheckingBC].SetData(c4d.DESC_PARENTGROUP, c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA), c4d.DescLevel(config['Parent group id'], c4d.DTYPE_GROUP, 0)))
BaseContainerVariable(config['Group container'],'GroupContainerId')
CountCheckingCont = 0
if (len(config['Base container']) > 0):
CountCheckingCont = len(config['Group container']) - 1
config['Group container'][CountCheckingCont] = c4d.BaseContainer()
if (config['effect'] == 'hide'):
for indexLoop in range(0, len(layer_list)):
config['Group container'][CountCheckingCont].SetString(indexLoop, "Texture " + str(indexLoop + 1))
config['Base container'][CountCheckingBC].SetContainer(c4d.DESC_CYCLE, config['Group container'][CountCheckingCont])
self.userdataGroup.SetUserDataContainer([c4d.ID_USERDATA, userDataId], config['Base container'][CountCheckingBC])
if (config['effect'] == 'hide'):
active_texture = self.userdataGroup[c4d.ID_USERDATA,userDataId]
if (active_texture >= count_texture):
self.userdataGroup[c4d.ID_USERDATA,userDataId] = count_texture - 1
active_texture = self.userdataGroup[c4d.ID_USERDATA,userDataId]
for index_active_texture in range(0,count_texture):
if (index_active_texture == active_texture):
layer_list[index_active_texture].SetParameter(c4d.LAYER_S_PARAM_ALL_ACTIVE, True)
else:
layer_list[index_active_texture].SetParameter(c4d.LAYER_S_PARAM_ALL_ACTIVE, False)
c4d.EventAdd()
config['shader'].Message(c4d.MSG_CHANGE)
def RandomButton(self,config,title,userDataId):
BaseContainerVariable(config['Base container'],'BaseContainerId')
CountCheckingBC = 0
if (len(config['Base container']) > 0):
CountCheckingBC = len(config['Base container']) - 1
config['Base container'][CountCheckingBC] = title + 'BaseContainer'
config['Base container'][CountCheckingBC] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_BUTTON)
else:
config['Base container'][0] = title + 'BaseContainer'
config['Base container'][0] = c4d.GetCustomDatatypeDefault(c4d.DTYPE_BUTTON)
config['Base container'][CountCheckingBC].SetString(c4d.DESC_NAME, title)
config['Base container'][CountCheckingBC].SetString(c4d.DESC_SHORT_NAME, title)
config['Base container'][CountCheckingBC].SetInt32(c4d.DESC_CUSTOMGUI, c4d.CUSTOMGUI_BUTTON)
config['Base container'][CountCheckingBC].SetData(c4d.DESC_PARENTGROUP, c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA), c4d.DescLevel(config['Parent group id'], c4d.DTYPE_GROUP, 0)))
BaseContainerVariable(config['Group container'],'GroupContainerId')
CountCheckingCont = 0
if (len(config['Base container']) > 0):
CountCheckingCont = len(config['Group container']) - 1
config['Group container'][CountCheckingCont] = c4d.BaseContainer()
config['Base container'][CountCheckingBC].SetContainer(c4d.DESC_CYCLE, config['Group container'][CountCheckingCont])
self.userdataGroup.SetUserDataContainer([c4d.ID_USERDATA, userDataId], config['Base container'][CountCheckingBC])
def main():
pass
def LaunchUpdate():
Interface = op.GetObject()
Objects = Interface.GetDown()
indexBc = []
groupBc = []
InterfaceGroup = bcSettings().Group(indexBc,groupBc)
base_controllers(op,Objects).Group(InterfaceGroup,'Interface',1)
ObjectsGroup = bcSettings().Group(indexBc,groupBc,3,True,1)
base_controllers(op,Objects).Group(ObjectsGroup,'Objects',2)
ObjectsCycle = bcSettings().CycleObj(indexBc,groupBc,2,True)
base_controllers(op,Objects).CycleObj(ObjectsCycle,'Object',3)
active_Ttag = Objects.GetChildren()[op[c4d.ID_USERDATA,3]].GetFirstTag()
active_Ttag = active_Ttag.GetNext()
active_mat = active_Ttag.GetMaterial()
if active_mat is None:
return
shader = active_mat[c4d.MATERIAL_COLOR_SHADER]
if shader is None:
return
TextureCycle = bcSettings().CycleTex(indexBc,groupBc,'hide',shader,2)
base_controllers(op,Objects).CycleTex(TextureCycle,'Texture',4)
ObjectRandomButton = bcSettings().RandomButton(indexBc,groupBc,2)
base_controllers(op,Objects).RandomButton(ObjectRandomButton,'Random',5)
def randomId_new(index,data):
index.append(data)
return index
def message(id, data):
if id == c4d.MSG_DESCRIPTION_POSTSETPARAMETER:
print data['descid']
LaunchUpdate()
if id == c4d.MSG_DESCRIPTION_COMMAND:
randomButtons = [5] #Random buttons Ids
buttonID = data['id']
SubList = [] #container storing id's values to have to changing
SubList = randomId_new(SubList,[3,4])#filling the container
if buttonID[0].id == c4d.ID_USERDATA:#check for user data
for RandomButtonId in range (0,len(randomButtons)):#loop for each button
if buttonID[1].id == randomButtons[RandomButtonId]:#check button ID
for SublistId in range (0,len(SubList[RandomButtonId])):
LaunchUpdate() # we can launch an update of the ui
RandomLimit = 0 #limit for randint
for id, bc in op.GetUserDataContainer():
if (id == c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA, c4d.DTYPE_SUBCONTAINER,0), c4d.DescLevel(SubList[RandomButtonId][SublistId]))): #check id
cycleBC = bc.GetContainer(c4d.DESC_CYCLE)
for element in cycleBC: #define len of cycleList
RandomLimit += 1
op[c4d.ID_USERDATA,SubList[RandomButtonId][SublistId]] = randint(0,RandomLimit - 1) #generate random value
print(str(SubList[RandomButtonId][SublistId]) + ': ' + str(RandomLimit)) #checking to console
Cheers
Manuel