Building a Character Object [SOLVED]
-
On 01/06/2016 at 01:44, xxxxxxxx wrote:
Hello,
since the Character object does not provide a dedicated API one must access its internal data to utilize it. This is not documented and not further supported.
You would have to read the object's parameter description to search for the IDs of the templates and identify them by their name. Also you would have to access an internal container to get the settings of the long buttons that are used to create the components. You can identify the buttons by their names and "press" them by sending a specific message to the Character object.
# get object description description = op.GetDescription(c4d.DESCFLAGS_DESC_0) if description is None: return # check parameter description for bc, paramid, groupid in description: # check "Template" parameter description if paramid[0].id == c4d.ID_CA_CHARACTER_TEMPLATE: # get cycle content cycle = bc.GetContainer(c4d.DESC_CYCLE) for id, data in cycle: print(str(id) + " " + data) # check for character components if paramid[0].id == c4d.ID_CA_CHARACTER_TEMPLATE_CONTAINER: print("Full Parameter ID: " + str(paramid)) # check cycle content cycle = bc.GetContainer(c4d.DESC_CYCLE) for id, data in cycle: print(str(id) + " " + data) # press the "button" by sending a message message = {} message['id'] = paramid op.Message(c4d.MSG_DESCRIPTION_COMMAND, message)
Best wishes,
Sebastian -
On 01/06/2016 at 09:27, xxxxxxxx wrote:
Woohoo this is super helpful thank you so much! I would have never been able to figure this all out on my own. I do have one more question, I can't seem to figure out how to find the IDs of the next components after I build the first one. Example: create the Advanced Biped Character, using your technique to create the "Root", now to build the "Spine" you need to be selected on the Root, but then I can not find the paramid for "Spine". I tried looking for the paramid for the "Spine" but can't seem to find it. Do you know how I can access the buttons that only show up after you build the parent components? Thank you so much. Bummer that the Character object does not have a documented API, I guess it is not used enough
-
On 02/06/2016 at 00:18, xxxxxxxx wrote:
Hello,
to get the Description showing the buttons for the sub-components you must select the component object but access the Description of the actual Character object.
Best wishes,
Sebastian -
On 02/06/2016 at 08:08, xxxxxxxx wrote:
Waaaa! Got it right a way! Why did I not to think of trying it thay way. Thank you very much Sebastian this is very helpful. I appreceate all of your help.
-
On 27/11/2016 at 00:08, xxxxxxxx wrote:
I just stumbled upon this. I don't quite understand how to build subsequent components. The code Sebastian posted successfully builds the Root component. The issue I'm seeing is that regardless, the first paramid is the same. So even though Root was created, event if I select root but run GetDescription still on the character object, it will print the right component name, but it will not build the spine, even thought it worked just fine for the root. Am I missing something?
-
On 28/11/2016 at 00:39, xxxxxxxx wrote:
Hello,
could you please post some code showing what you are doing?
best wishes,
Sebastian -
On 28/11/2016 at 09:22, xxxxxxxx wrote:
Hey Sebastian,
The code I was using was pretty much the same as the code you had posted. The only difference was instead of"
description = op.GetDescription(c4d.DESCFLAGS_DESC_0), I had replaced op with charObj, which is a variable i got via a doc.SearchObject("Character"). I did that because one of the things here mentioned running the code on the char object whilest a component was selected. This creates the root component and selects it but it doesn't create any others, despite the fact that it will print the next component(Spine FK/IK). -
On 29/11/2016 at 00:32, xxxxxxxx wrote:
Hello,
the posted script only does one thing. It loops through the description and "presses" the buttons. The script is only intended to show how to obtain the needed parameter IDs and how to "press" the button, nothing else.
So when you execute the script once, it only presses one button ("Root"). If the script should create something else it must run again (or you have to code the "pressing" of the next button yourself).
The script does not print "the next component".
best wishes,
Sebastian -
On 29/11/2016 at 23:49, xxxxxxxx wrote:
Hey Sebastian,
So here's my script. It's very much like the one you posted but changed as I mentioned and a couple things commented out.
import c4d
from c4d import gui
#Welcome to the world of Pythondef main() :
# get object description
charObj=doc.SearchObject("Character")
description = charObj.GetDescription(c4d.DESCFLAGS_DESC_0)
if description is None:
return
# check parameter description
for bc, paramid, groupid in description:
# check "Template" parameter description
if paramid[0].id == c4d.ID_CA_CHARACTER_TEMPLATE:
# get cycle content
cycle = bc.GetContainer(c4d.DESC_CYCLE)
#for id, data in cycle:
# print(str(id) + " " + data)
# check for character components
if paramid[0].id == c4d.ID_CA_CHARACTER_TEMPLATE_CONTAINER:
print("Full Parameter ID: " + str(paramid))
# check cycle content
cycle = bc.GetContainer(c4d.DESC_CYCLE)
for id, data in cycle:
print(str(id) + " " + data)
# press the "button" by sending a message
message = {}
message['id'] = paramid
op.Message(c4d.MSG_DESCRIPTION_COMMAND, message)
if __name__=='__main__':
main()Now, if you create a character object and select it and then run the script, it will print the following:
"Full Parameter ID: ((2113,5,0), (1000, 150))
1000 Root"And it will create and then select the Root. So this gets the Description of the Character Object, and presses a button based on the selected object(op.Message).
Now, with the Root still selected, run the script again. This time it will print:
"Full Parameter ID: ((2113, 5,0),(1000,15,0))
1000 Spine (IK/FK Blend)"yet it won't create that button. Even though op, is now our Root component object, and it displays the right component name, but when it tries to click the button like you did for Root, it doesn't do it. Why is that? That's the part I don't quite understand. It also seems to generate the same paramid, I assume that the first one always is that number(1000), and it goes up from there.
But why doesn't it keep creating components as I keep running the script?
-
On 30/11/2016 at 08:04, xxxxxxxx wrote:
Hello,
you have to send the message to the character object, not the "Root" object. Just like in the original script.
best wishes,
Sebastian -
On 01/12/2016 at 23:14, xxxxxxxx wrote:
Thanks for that Sebastian. It works. But now I'm running into an issue. I want to run through a loop and build components whos names I specify. Here's what I have:
import c4d
from c4d import gui
#Welcome to the world of Pythondef main() :
# get object description
parents=['Character', 'Root', 'Spine', 'Spine', 'Spine', 'Spine']
buttonNames=['Root', 'Spine (IK/FK Blend)', 'Arm (IK/FK Bendy)', 'Jaw', 'Eye', 'Leg (IK/FK Bendy)']
charObj=doc.SearchObject('Character')
for id2, buttonName in enumerate(buttonNames) :
description = charObj.GetDescription(c4d.DESCFLAGS_DESC_0)
if description is None:
return
# check parameter description
for bc, paramid, groupid in description:
# check for character components
if paramid[0].id == c4d.ID_CA_CHARACTER_TEMPLATE_CONTAINER:
# check cycle content
cycle = bc.GetContainer(c4d.DESC_CYCLE)for id, data in cycle:
print(str(id) + " " + data)
if data==buttonName:
# press the "button" by sending a message
message = {}
message['id'] = paramid
charObj.Message(c4d.MSG_DESCRIPTION_COMMAND, message)
c4d.DrawViews(c4d.DRAWFLAGS_FORCEFULLREDRAW)if __name__=='__main__':
main()However, it just is always saying Root first. The data from cycle is not updating? Is that the issue or am I doing something stupid?
The other question I have: There are different behaviors for clicking the button based on keyboard modifiers(ie different things happen if I SHIFT+Click on the button, CTRL+Click, or CTRL+SHIFT click). Is it possible to pass these modifiers into the message so that when i simulates the button click it can simulate the button click with CTRL+SHIFT pressed?
-
On 02/12/2016 at 07:55, xxxxxxxx wrote:
Hello,
it seems that the Character object only works properly when used manually. The Description returned is always the same, the Character object (and the whole Character System in the background) seems to update internal data at several stages of the event system and scene execution. I'm afraid it is not possible to properly update the Character object from within a script.
If a key is pressed is detected with functions like GetInputState(). This has nothing to do with the MSG_DESCRIPTION_COMMAND and cannot be emulated.
best wishes,
Sebastian