Detailed information on dynamic parameters[SOLVED]



  • On 28/05/2015 at 06:09, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R15+ 
    Platform:   Windows  ; Mac  ;  
    Language(s) :     C++  ;

    ---------
    Hi!

    I'm writing a plugin that creates a lot of parameters dynamically. Unfortunately there is little information
    out there on how to correctly  set up dynamic parameters in GetDDescription()  and the system seems to
    be extremely fragile and error prone.

    I just spent two hours finding out how to create groups, buttons and separators and, although I can
    create them now and I don't get a Breakpoint triggered from  ge_container.h(211)  anymore, there are still
    problems. (Eg. setting  DESC_COLUMNS  and DESC_SCALEH  seems to have no effect at all, when I press
    the button I still get the breakpoint, etc.).

    Is there any complete  information out there that I have missed or is there any chance this will get
    completely documented soon? There are snippets all over the place, but many details aren't covered.

    Thanks in advance,
    Niklas



  • On 28/05/2015 at 08:21, xxxxxxxx wrote:

    Hello,

    the only documentation currently available is – well – the documentation. We agree that a lot of information can be added and we a currently working to improve both the documentation and the examples. Keep an eye on GitHub where new SDK examples are published.

    As always you are free to ask specific questions on this forum.

    Best wishes,
    Sebastian



  • On 28/05/2015 at 23:04, xxxxxxxx wrote:

    Ok thanks Sebastian.

    Maybe we can fill this topic with some of the information I was missing :-)

    a) I want to create a Separator but I have to specify a DescID. In a description resource file, you don't
    need to specify an ID for a separator or even for a group if you don't want to. What IDs will be used
    then? And can I do this in GetDDescription()?

    I create the Separator with

    	inline DescID MakeSeparator(Int32 id, const DescID& parentId, Bool line)
    	{
    		DescID did{DescLevel{id, DTYPE_SEPARATOR, m_creator}};
    		if (!this->CheckSingleID(id)) return did;
    		BaseContainer bc;
    		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_SEPARATOR);
    		bc.SetBool(DESC_SEPARATORLINE, line);
    		DebugAssert(m_desc->SetParameter(did, bc, parentId));
    		return did;
    	}
    

    b) I want to create a group with 2 columns, but it just won't have two columns. The string and the
    button widgets are not on the same line.

    	inline DescID MakeGroup(
    		Int32 id, const DescID& parentId, const String& name,
    		const String& shortName, Bool scaleH = true, Int32 columns = 1)
    	{
    		DescID did{DescLevel{id, DTYPE_GROUP, m_creator}};
    		if (!this->CheckSingleID(id)) return did;
    		BaseContainer bc;
    		bc.SetInt32(DESC_CUSTOMGUI, 0);
    		bc.SetString(DESC_NAME, name);
    		bc.SetString(DESC_SHORT_NAME, (shortName.Content() ? shortName : name));
    		bc.SetInt32(DESC_COLUMNS, columns);
    		DebugAssert(m_desc->SetParameter(did, bc, parentId));
    		return did;
    	}
    

    The group and its children are created like this:

    	const DescID topGroupId = dh.MakeGroup(this->TopGroupID(), parentId, "", "", true, 2);
      
    	// Add the channel name parameter.
    	const DescID channelNameId = dh.MakeID(this->ChannelNameID(), DTYPE_STRING);
    	if (dh.CheckSingleID(channelNameId)) {
    		bc = GetCustomDataTypeDefault(DTYPE_STRING);
    		bc.SetString(DESC_NAME, "Channel Name");
    		bc.SetString(DESC_SHORT_NAME, "Channel Name");
    		bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_OFF);
    		desc->SetParameter(channelNameId, bc, topGroupId);
    	}
    	dh.MakeButton(this->RemoveButtonID(), topGroupId, "Remove", "-");
    

    c) The MakeButton() function looks like this: But when I press the button, I get a breakpoint in
    ge_container.h triggered (just as when you didn't initialize an entry in the container or didn't specify
    the dtype  in a DescLevel ).

    	inline DescID MakeButton(
    		Int32 id, const DescID& parentId, const String& name,
    		const String& shortName)
    	{
    		DescID did{DescLevel{id, DTYPE_BUTTON, m_creator}};
    		if (!this->CheckSingleID(id)) return did;
    		BaseContainer bc;
    		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
    		bc.SetString(DESC_NAME, name);
    		bc.SetString(DESC_SHORT_NAME, (shortName.Content() ? shortName : name));
    		DebugAssert(m_desc->SetParameter(did, bc, parentId));
    		return did;
    	}
    

    Can you give me any hints? Thanks!

    -Niklas



  • On 29/05/2015 at 01:58, xxxxxxxx wrote:

    The SDK example was indeed very helpful. I'm not exactly sure what the actual problem was, but now
    all the issues I listed above are gone, except that DESC_SCALEH doesn't seem to have any effect on
    the group description.

    It might be that I use GetCustomDataTypeDefault() now, but I tested it with Python before and the
    container returned by it for DTYPE_GROUP, DTYPE_BUTTON and DTYPE_SEPARATOR were empty.

    This is what the functions look like now:
    (PS: I used the LookAtCamera example as a reference)

    	inline Bool CheckSingleID(const DescID& id)
    	{
    		return !m_singleid || id.IsPartOf(*m_singleid, nullptr);
    	}
      
    	inline DescID MakeButton(
    		Int32 id, const DescID& parentId, const String& name,
    		const String& shortName)
    	{
    		DescID cid = DescLevel(id, DTYPE_BUTTON, 0);
    		if (!this->CheckSingleID(id)) return cid;
    		BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON);
    		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
    		bc.SetString(DESC_NAME, name);
    		if (shortName.Content())
    			bc.SetString(DESC_SHORT_NAME, shortName);
    		DebugAssert(m_desc->SetParameter(cid, bc, parentId));
    		return cid;
    	}
      
    	inline DescID MakeGroup(
    		Int32 id, const DescID& parentId, const String& name,
    		const String& shortName, Bool scaleH = true, Int32 columns = 1)
    	{
    		DescID cid = DescLevel(id, DTYPE_GROUP, 0);
    		if (!this->CheckSingleID(id)) return cid;
    		BaseContainer bc = GetCustomDataTypeDefault(DTYPE_GROUP);
    		bc.SetString(DESC_NAME, name);
    		if (shortName.Content())
    			bc.SetString(DESC_SHORT_NAME, shortName);
    		bc.SetInt32(DESC_COLUMNS, columns);
    		bc.SetBool(DESC_SCALEH, scaleH);
    		DebugAssert(m_desc->SetParameter(cid, bc, parentId));
    		return cid;
    	}
      
    	inline DescID MakeSeparator(Int32 id, const DescID& parentId, Bool line)
    	{
    		DescID cid = DescLevel(id, DTYPE_SEPARATOR, 0);
    		if (!this->CheckSingleID(id)) return cid;
    		BaseContainer bc = GetCustomDataTypeDefault(DTYPE_SEPARATOR);
    		bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_SEPARATOR);
    		bc.SetBool(DESC_SEPARATORLINE, line);
    		DebugAssert(m_desc->SetParameter(cid, bc, parentId));
    		return cid;
    	}
    


  • On 29/05/2015 at 02:37, xxxxxxxx wrote:

    Hello,

    yes, using GetCustomDataTypeDefault() seems to be a crucial part and is recommended.

    Also, it seems that DESC_SCALEH must be set using SetInt32() :

      
    BaseContainer bc = GetCustomDataTypeDefault(DTYPE_GROUP);  
      
    bc.SetString(DESC_NAME, "Group");  
    bc.SetInt32(DESC_COLUMNS, 2);  
    bc.SetInt32(DESC_DEFAULT, 1);  
    bc.SetInt32(DESC_SCALEH, 1);  
      
    description->SetParameter(DescLevel(groupID, DTYPE_GROUP, 0), bc, ID_GROUP_DYAMIC);  
    

    best wishes,
    Sebastian



  • On 29/05/2015 at 03:41, xxxxxxxx wrote:

    Hi Sebastian,

    Hm I can't see any difference there. But maybe that's just how the groups work? Maybe they can't be
    scaled horizontally with more than one column. But I found a way around it: I set DESC_SCALEH on the
    element that I actually want to be scaled and the group will appear the way I want it. :-)

    	if (dh.CheckSingleID(channelNameId)) {
    		bc = GetCustomDataTypeDefault(DTYPE_STRING);
    		bc.SetString(DESC_NAME, "Channel Name");
    		bc.SetBool(DESC_SCALEH, true);
    		bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_OFF);
    		desc->SetParameter(channelNameId, bc, topGroupId);
    	}
    

    Best regards,
    Niklas



  • On 01/06/2015 at 08:30, xxxxxxxx wrote:

    Hi, I ran into another problem. My dynamic description is not displayed on Mac. And I have no idea why.
    I checked twice that the code is executed. And it works fine on Windows. 😠

    Someone have a clue what this could be about? Thank you

    Update:  It seems to be a problem with the way I create the Group.  The parameters inside the group
    are displayed when I change their parent ID to a group that already exists, but not with the ID of the
    group that I create dynamically. Of course, the group has the parent ID of an existing group already.

    	inline DescID MakeGroup(
    		Int32 id, const DescID& parentId, const String& name,
    		const String& shortName, Int32 columns = 1, Bool defaultOpen = false)
    	{
    		DescID cid = DescLevel(id, DTYPE_GROUP, 0);
    		if (!this->CheckSingleID(id)) return cid;
    		BaseContainer bc = GetCustomDataTypeDefault(DTYPE_GROUP);
    		bc.SetString(DESC_NAME, name);
    		if (shortName.Content())
    			bc.SetString(DESC_SHORT_NAME, shortName);
    		bc.SetInt32(DESC_DEFAULT, defaultOpen);
    		bc.SetInt32(DESC_COLUMNS, columns);
    		bc.SetBool(DESC_SCALEH, 1);
    		DebugAssert(m_desc->SetParameter(cid, bc, parentId));
    		return cid;
    	}
    


  • On 01/06/2015 at 09:07, xxxxxxxx wrote:

    Now this is hilarious 😂 Of course, DebugAssert won't even evaluate the expression in a release build.
    And I called Description::SetParameter() in DebugAssert(). Now that explains it all. :-)


Log in to reply