Solved Change parameter's unit type

Hi everyone,

Trying to create a functionality, when parameter's unit would be changed based on selected mode - either real unit, either percentage.
I'm pretty sure it has to be handled within the GetDDescription method, but I can't find related example or doc.

Here's what I need, I have integer parameter TESTPLUGIN_MODE, which might be one of the TESTPLUGIN_DISTANCE or TESTPLUGIN_PERCENTAGE values.
And I have float offset parameter TESTPLUGIN_OFFSET

So if TESTPLUGIN_MODE equals to TESTPLUGIN_DISTANCE, then TESTPLUGIN_OFFSET unit should be METER
else unit should be PERCENT;

Below is my res file "testplugin.res":

CONTAINER Otestplugin {
    NAME Otestplugin;
    INCLUDE Obase;

    GROUP ID_OBJECTPROPERTIES {
        DEFAULT 1;

        GROUP {
            LONG TESTPLUGIN_MODE {
                CYCLE {
                    TESTPLUGIN_DISTANCE;
                    TESTPLUGIN_PERCENTAGE;
                };
                DEFAULT TESTPLUGIN_DISTANCE;
            }
            
            REAL TESTPLUGIN_OFFSET {
                CUSTOMGUI LONGSLIDER;
                MINSLIDER -1000; MAXSLIDER 1000;
                DEFAULT 0;
            }
        }
    }
}

And Otestplugin.pyp part (actually nothing):

  def GetDDescription(self, node, description, flags):
    if not description.LoadDescription(node.GetType()): return False

    data = node.GetDataInstance()

    return (True, flags | c4d.DESCFLAGS_DESC_LOADED)

Parameter units are defined with the c4d.DESC_UNITproperty. See Description Settings Manual.

To change the properties of an existing parameter, one would have to translate this code to Python: Description Manual.

Parameter units are defined with the c4d.DESC_UNITproperty. See Description Settings Manual.

To change the properties of an existing parameter, one would have to translate this code to Python: Description Manual.

Hi,

in case you struggle, here is an example for Python, which hides stuff based on based on some booleans. There is also a Python specific resource for that what @PluginStudent already linked you. You can find it here.

Cheers,
zipit

def GetDDescription(self, node, description, flags):
    """Show and hide parameters based on the sampling type.

    Args:
        node (c4d.GeListNode): An instance of a TopologyMap tag.
        description (c4d.Description): The description of the tag.
        flags (int): The flags for the description operation.

    Returns:
        bool or tuple(bool, int): Success of the description modification.
    """

    if (not description or not node or
            not description.LoadDescription(node.GetType())):
        return False

    # Here I am polling the passed description for a specific attribute.
    bc = description.GetParameterI(c4d.DescID(
        c4d.DescLevel(c4d.IDC_CURVATURE_FOLD)))
    if bc:
        # Here I am just polling the node, i.e. the tag in this case, for
        # an attribute based on which we want to do something.
        state = node[c4d.IDC_SAMPLING_TYPE] != c4d.IDV_TYPE_CURVATURE
        # And here I modify the description, see c4d.Description for details.
        bc.SetBool(c4d.DESC_HIDE, state)

    # And the rest is just the same stuff, but for other attributes.

    # Orientation
    bc = description.GetParameterI(c4d.DescID(
        c4d.DescLevel(c4d.IDC_ORIENTATION_OPTIONS)))
    if bc:
        state = node[c4d.IDC_SAMPLING_TYPE] != c4d.IDV_TYPE_ORIENTATION
        bc.SetBool(c4d.DESC_HIDE, state)

    # Thickness
    bc = description.GetParameterI(c4d.DescID(
        c4d.DescLevel(c4d.IDC_THICKNESS_SAMPLES)))
    if bc:
        state = node[c4d.IDC_SAMPLING_TYPE] != c4d.IDV_TYPE_THICKNESS
        bc.SetBool(c4d.DESC_HIDE, state)

    return (True, flags | c4d.DESCFLAGS_DESC_LOADED)

MAXON SDK Specialist
developers.maxon.net

@PluginStudent thanks

@zipit thanks a lot, but based on c++ docs made this (seems there are just more checking):

  def GetDDescription(self, node, description, flags) :  
    data = node.GetDataInstance()
    if data is None or not description.LoadDescription(node.GetType()): return False
    
    singleID = description.GetSingleDescID()
    paramID = c4d.DescID(c4d.DescLevel(c4d.TESTPLUGIN_OFFSET))
 
    if ( singleID is None or paramID.IsPartOf(singleID)[0] ):
      bc = description.GetParameterI(paramID)
      if (bc):
        if data.GetLong(c4d.TESTPLUGIN_MODE) == TESTPLUGIN_MODE_DISTANCE: bc.SetLong(c4d.DESC_UNIT, c4d.DESC_UNIT_METER)
        else: bc.SetLong(c4d.DESC_UNIT, c4d.DESC_UNIT_PERCENT)

    return (True, flags | c4d.DESCFLAGS_DESC_LOADED)