Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login

    FieldList Enable Clamping

    Cinema 4D SDK
    r20 sdk c++
    2
    5
    750
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      JohnTerenece
      last edited by

      Hi.

      I'm working on a plugin that utilizes a FieldList control that I am creating using custom data type CUSTOMDATATYPE_FIELDLIST. My issue comes in with the "Enable/Disable Value Clamping" control and not being able to change it using code.

      I've looked through the sdk in relation to the FieldList entry and couldn't find anything that refrences it. The closest thing I could find was the FIELDLIST_FLAGS::CLAMPOUTPUT which not suprisingly had no effect on the control when used with SetFlags.

      This is my code for creating my FieldList control.

      	DescID DescFieldGroup = DescLevel(idFieldGroup, DTYPE_GROUP, 0);
      	if (!singleid || DescFieldGroup.IsPartOf(*singleid, NULL))
      	{
      		BaseContainer bc;
      		bc = GetCustomDataTypeDefault(DTYPE_GROUP);
      		bc.SetInt32(DESC_COLUMNS, 1);
      		bc.SetBool(DESC_SCALEH, TRUE);
      		if (!description->SetParameter(DescFieldGroup, bc, idMainGroup))
      			return TRUE;
      	}
      	cid = DescLevel(idGrowField, CUSTOMDATATYPE_FIELDLIST, 0);
      	if (!singleid || cid.IsPartOf(*singleid, NULL))
      	{
      
      		BaseContainer bc;
      		bc = GetCustomDataTypeDefault(CUSTOMDATATYPE_FIELDLIST);
      		bc.SetBool(DESC_FIELDLIST_NOCOLOR, TRUE);
      		
      		bc.SetBool(DESC_FIELDLIST_NODIRECTION, TRUE);
      		bc.SetBool(DESC_FIELDLIST_NOROTATION, TRUE);
      
      		if (!description->SetParameter(cid, bc, DescFieldGroup))
      			return TRUE;
      	}
      

      Is it possible to change the control via code or can it only be changed manually by a user.

      Any help would be greatly appreciated.

      John Terenece

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by Manuel

        hi,

        It is not clear what parameter you want to modify. The code you are sharing is inside GetDDescription i suppose.
        You need to user SetParameter on your node itself. The tricky part is to build the DescID to target the right parameter.
        You need the ID of your fieldList, the ID of the layer on that list and the parameter ID on that layer. All level must be defined as CUSTOMDATATYPE_FIELDLIST.

        You must search for the layer inside your field list and call GetUniqueID on it. This will return the correct ID you must use in your DescLevel. Below a script that will flip/flop the parameter "enable/value" for the first layer in the list.
        7be77196-b02c-4830-8ea6-6fbf8fef22bd-image.png

        I created a python script for r20 and for more recent version

        R20 version

        
        import c4d
        
        def main():
            # Called when the plugin is selected by the user. Similar to CommandData.Execute.
            effector = op
            if effector is None:
                raise ValueError("there is no active objet")
            
            fieldList  = effector[c4d.FIELDS]
            root = fieldList.GetLayersRoot()
            clampLayer = root.GetDown()
            
            # Retriving the unique ID allows to construct the DescID to target the right parameter.
            clampUniqueID = clampLayer.GetUniqueID()
            
            # Building the DescID
            # This ID is composed of three level:
            # the first one define the field list parameter,
            # the second define  the layer, that is why we need its UniqueID,
            # the last level define the parameter in this layer.
            # Note that all DescLevel are of DataType CUSTOMDATATYPE_FIELDLIST
            enableID = c4d.DescID(c4d.DescLevel(c4d.FIELDS, c4d.CUSTOMDATATYPE_FIELDLIST), c4d.DescLevel(clampUniqueID,  c4d.CUSTOMDATATYPE_FIELDLIST),  c4d.DescLevel(c4d.ID_FIELDLAYER_ENABLE_VALUE, c4d.CUSTOMDATATYPE_FIELDLIST))
        
            # Retreving the value using GetParameter on the effector itself.
            value  = effector.GetParameter(enableID, c4d.DESCFLAGS_GET_NONE)
            # Define the oposite value
            effector.SetParameter(enableID, not value, c4d.DESCFLAGS_SET_NONE)
        
        
            c4d.EventAdd()
        if __name__ == '__main__':
            main()
        

        Same example but for more recent version of c4d.

        from typing import Optional
        import c4d
        
        doc: c4d.documents.BaseDocument  # The active document
        op: Optional[c4d.BaseObject]  # The active object, None if unselected
        
        def main() -> None:
            # Called when the plugin is selected by the user. Similar to CommandData.Execute.
            effector :c4d.BaseObject = op
            if effector is None:
                raise ValueError("there is no active objet")
            
            fieldList :c4d.FieldList = effector[c4d.FIELDS]
            root :c4d.GeListHead = fieldList.GetLayersRoot()
            clampLayer :c4d.modules.mograph.FieldLayer = root.GetDown()
            
            # Retriving the unique ID allows to construct the DescID to target the right parameter.
            clampUniqueID = clampLayer.GetUniqueID()
            
            # Building the DescID
            # This ID is composed of three level:
            # the first one define the field list parameter,
            # the second define  the layer, that is why we need its UniqueID,
            # the last level define the parameter in this layer.
            # Note that all DescLevel are of DataType CUSTOMDATATYPE_FIELDLIST
            enableID :c4d.DescID = c4d.DescID(c4d.DescLevel(c4d.FIELDS, c4d.CUSTOMDATATYPE_FIELDLIST), c4d.DescLevel(clampUniqueID,  c4d.CUSTOMDATATYPE_FIELDLIST),  c4d.DescLevel(c4d.ID_FIELDLAYER_ENABLE_VALUE, c4d.CUSTOMDATATYPE_FIELDLIST))
        
            # Retreving the value using GetParameter on the effector itself.
            value : bool  = effector.GetParameter(enableID, c4d.DESCFLAGS_GET_NONE)
            # Define the oposite value
            effector.SetParameter(enableID, not value, c4d.DESCFLAGS_SET_NONE)
        
        
            c4d.EventAdd()
        if __name__ == '__main__':
            main()
        

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        J 1 Reply Last reply Reply Quote 0
        • J
          JohnTerenece @Manuel
          last edited by

          @Manuel
          Thanks for the reply.

          What I'm trying to change is this control.

          Clamp.png

          John Terenece

          1 Reply Last reply Reply Quote 0
          • ManuelM
            Manuel
            last edited by Manuel

            hi,

            for this, you must use the function SetFlags on the Field data and update the data on the object. The flag that must be set is FIELDLIST_FLAGS::CLAMPOUTPUT

            Unfortunately, the UI do not update, you must deselect and reselect the object. I did not find anything yet to address this issue.
            I used c++ this time to be sure nothing was wrong with python.

            BaseObject* op = doc->GetActiveObject();
            if (!op)
            	return maxon::NullptrError(MAXON_SOURCE_LOCATION);
            
            GeData data;
            op->GetParameter(FIELDS, data, DESCFLAGS_GET::NONE);
            FieldList* fl = static_cast<FieldList*>(data.GetCustomDataType(CUSTOMDATATYPE_FIELDLIST));
            fl->SetFlags(FIELDLIST_FLAGS::CLAMPOUTPUT, false);
            op->SetParameter(FIELDS, GeData(CUSTOMDATATYPE_FIELDLIST, *fl), DESCFLAGS_SET::NONE);
            

            python code just in case

                fl = op[c4d.FIELDS]
                toggle = fl.CheckFlag(c4d.FIELDLIST_FLAGS_CLAMPOUTPUT)
                fl.SetFlags(c4d.FIELDLIST_FLAGS_CLAMPOUTPUT, not toggle)
                op[c4d.FIELDS] = fl
            

            Cheers,
            Manuel

            MAXON SDK Specialist

            MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • J
              JohnTerenece
              last edited by

              Thanks, that was exactly what I was looking for.

              John Terenece

              1 Reply Last reply Reply Quote 0
              • First post
                Last post