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
    • Login

    Can REAL MIN / MAX value be changed on Init?

    Bugs
    2023 python s26 sdk
    2
    20
    3.8k
    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.
    • mocolocoM
      mocoloco
      last edited by

      @ferdinand,

      I found the problem. For a reason I can't explain, going through the new assignment once on the first call of GetDDescription() isn't enough. I thought that I could do the change once on first plugin TAG load/use, then avoid to going through this change each time GetDDescription() is called. But that's isn't the case. It seems that the change need to be perpetual and need to be parsed and evaluated constantly to be seen and changed in the interface ( honestly I found this weird and not really optimised in terms of coding ).

      So, by getting rid of the flag FIRST_INIT (which wasn't in the code above), the code does work as expected.

      Maybe could you explain me why this repetitive reassignment is needed?

      Thanks a lot for your prompt support and all detailed explanation you are providing, it does help a lot.
      Cheers,

      Christophe

      1 Reply Last reply Reply Quote 0
      • mocolocoM
        mocoloco
        last edited by mocoloco

        @ferdinand,

        There is something weird going on. I intend to change several sliders accordingly to Parameters, ID_X and ID_Y.
        I adapted the code accordingly, but it seems that only DESC_MAXSLIDER and DESC_MINSLIDER are took into account while DESC_MIN and DESC_MAX stick to previous values. Could that be a bug?

        Screenshot 2023-01-16 at 16.02.40.png

        I let in remarks the code that improve a bit better the result and allows ID_X to be fully set (MIN/MAX as well as MINSLIDER/MAXSLIDER), but the problems remains on ID_Y.

        Screenshot 2023-01-16 at 16.03.14.png

        Here the whole code of GetDDescription(),

        global Parameters
        Parameters = dict()
        Parameters['Xmin'] = -360.0
        Parameters['Xmax'] = 360.0
        Parameters['Ymin'] = -25.0
        Parameters['Ymax'] = 25.0
        
        def GetDDescription(self, node, description, flags):  
            if not description.LoadDescription(node.GetType()):
                return False  
        
            # Change Slider limits accordingly to Parameters values
            # Sliders to modifiy ID_X, ID_Y
        
        
            ## SLIDER ID_X
            if len(Parameters) > 0:
                paramID_X: c4d.DescID = c4d.DescID(c4d.DescLevel(ID_X, c4d.DTYPE_REAL, 0))
                single_X: c4d.DescID = description.GetSingleDescID()
                # Bail when there is a to be evaluated parameter and our parameter is not part off or equal to the to be evaluated parameter.
                if single_X and not paramID_X.IsPartOf(single_X):
                    return True, flags
                # if singleId[0] == mAXIS_X: print (f"singleID found: {singleId} ")
                # Get the description data container instance (GetParameter>I<) for the parameter we want to modify
                desc_X: c4d.BaseContainer = description.GetParameterI(paramID_X)
                if desc_X is None:
                    return True, flags
        
                # if single_X and paramID_X.IsPartOf(single_X):
                #     if paramID_A1.IsPartOf(single_X)[0]:
                        # Write the MAX and MAXSLIDER values based on UserDatas
                desc_X[c4d.DESC_MIN] = c4d.utils.DegToRad(Parameters["Xmin"])
                desc_X[c4d.DESC_MINSLIDER] = c4d.utils.DegToRad(Parameters["Xmin"])
                desc_X[c4d.DESC_MAX] = c4d.utils.DegToRad(Parameters["Xmax"])
                desc_X[c4d.DESC_MAXSLIDER] = c4d.utils.DegToRad(Parameters["Xmax"])
                # if single_X and paramID_X.IsPartOf(single_X):
                #     if paramID_X.IsPartOf(single_X)[0]:
                #         print (f"Found X: {paramID_X.IsPartOf(single_X)[0]} ")
                #         return (True, flags | c4d.DESCFLAGS_DESC_LOADED)
                        
        
                ## SLIDER ID_Y
                paramID_Y: c4d.DescID = c4d.DescID(c4d.DescLevel(mAXIS_Y, c4d.DTYPE_REAL, 0))
                single_Y: c4d.DescID = description.GetSingleDescID()
                # Bail when there is a to be evaluated parameter and our parameter is not part off or equal to the to be evaluated parameter.
                if single_Y and not paramID_Y.IsPartOf(single_Y):
                    return True, flags
                # Get the description data container instance (GetParameter>I<) for the parameter we want to modify
                desc_Y: c4d.BaseContainer = description.GetParameterI(paramID_Y)
                if desc_Y is None:
                    return True, flags
                # Write the MAX and MAXSLIDER values based on UserDatas
                desc_Y[c4d.DESC_MIN] = c4d.utils.DegToRad(Parameters["Ymin"])
                desc_Y[c4d.DESC_MINSLIDER] = c4d.utils.DegToRad(Parameters["Ymin"])
                desc_Y[c4d.DESC_MAX] = c4d.utils.DegToRad(Parameters["Ymax"])
                desc_Y[c4d.DESC_MAXSLIDER] = c4d.utils.DegToRad(Parameters["Ymax"])
                # if single_Y and paramID_A2.IsPartOf(single_Y):    
                #     if paramID_Y.IsPartOf(single_Y)[0]:
                #         print (f"Found Y: {paramID_Y.IsPartOf(single_Y)[0]} ")
                #         return (True, flags | c4d.DESCFLAGS_DESC_LOADED)
                    
        
           return (True, flags | c4d.DESCFLAGS_DESC_LOADED)
        

        Does this trick to change REALSLIDER MIN/MAX values intend to be associated to only on change, and not on several UI object?

        Thanks in advance,
        Cheers,

        Christophe

        1 Reply Last reply Reply Quote 0
        • mocolocoM
          mocoloco
          last edited by

          You can add the following code to see the values before and after new assignment. You will see that the values are correctly changed, but the change does not reach the interface for unknown reason.

          for k,v in desc_Y:
              print(f"Y New, Key {k} / Val {v}")
          
          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @mocoloco
            last edited by

            Hey @mocoloco,

            So, I gave it a spin and the root of your problems is that you defined your parameters as UNIT DEGREE where you and I used METER in the first examples. When you do so, you must define your values in radians, not degree when you write into the raw data.

            But there are also some weird things going on with DEGREE. First of all, min-max slider values are always set to null\None in the description container, no matter how often you write the values, and the general min/max values seem to be used instead. One could sort of make sense of that, but what is really weird how the first parameter in a group does behave.

            blahblah.gif
            Fig. I - Unit Degree: We set the min-max range and name for both parameters. Setting the name works on both, but the first parameter adopts a clamped range which is a weird mix of its old and new value. The second parameter works fine.

            Running the same code but using METER as a unit works without any issues.

            blahblah2.gif
            Fig. II - Unit Meter: Here both parameters work flawlessly.

            There is either a bug in the degree description handling, or you must jump through some hoops and set up the data in a specific way. I will not have the time to test this in more detail before next week. To help yourself, I would suggest defining either via user-data or a resource file a REAL DEGREE parameter and then reading out all its description values, looking for anything special that might be going on.

            Cheers,
            Ferdinand

            Code:

            """Implements a tag which drives the position of a host object procedurally or via tracks.
            """
            
            import c4d
            import typing
            
            class DynamicDescriptionTagData(c4d.plugins.TagData):
                """Implements a tag which drives the position of a host object procedurally or via tracks.
                """
                # The plugin ID.
                ID_PLUGIN: int = 1060463
            
                # What you dubbed "user data", a dictionary holding some description data to be injected at 
                # runtime. I just changed things a bit up and include/identify things over their ID instead
                # of made-up strings, but nothing would prevent you from having both, it would just be a bit
                # more complicated to parse such data:
                #
                # INTERFACE_DATA = [
                #     {
                #         "label": "Foo", 
                #         "id": c4d.DescId(...), 
                #         "data": [
                #             {"label": "Name", "id": c4d.DESC_NAME, "value": "Bar"},
                #             ...
                #         ]
                #     },
                #     ...
                # ]
                INTERFACE_DATA: list[tuple[c4d.DescID, dict[int, typing.Any]]] = [
                    (c4d.DescID(c4d.DescLevel(c4d.ID_OFF_X, c4d.DTYPE_REAL, 0)), 
                    {
                        c4d.DESC_NAME: "foo.x",
                        c4d.DESC_SHORT_NAME: "foo.x",
                        c4d.DESC_MIN: c4d.utils.DegToRad(-360.),
                        c4d.DESC_MAX: c4d.utils.DegToRad(360.),
                    }),
                    (c4d.DescID(c4d.DescLevel(c4d.ID_OFF_Y, c4d.DTYPE_REAL, 0)), 
                    {
                        c4d.DESC_NAME: "bar.y",
                        c4d.DESC_SHORT_NAME: "bar.y",
                        c4d.DESC_MIN: c4d.utils.DegToRad(-45.),
                        c4d.DESC_MAX: c4d.utils.DegToRad(45.),
                    }),
                ]
            
                DID_PARENT_GROUP: c4d.DescID = c4d.DescID(c4d.DescLevel(c4d.ID_GRP_STUFF, c4d.DTYPE_GROUP, 0))
                    
                def Init(self, node: c4d.GeListNode) -> bool:
                    """Called to initialize a DynDescription tag instance.
            
                    Args:
                        node: The BaseTag instance representing this plugin object.
                    """
                    self.InitAttr(node, float, c4d.ID_OFF_X)
                    self.InitAttr(node, float, c4d.ID_OFF_Y)
            
                    node[c4d.ID_OFF_X] = 0.
                    node[c4d.ID_OFF_Y] = 0.
            
                    return True
            
                def Execute(self, tag: c4d.BaseTag, doc: c4d.documents.BaseDocument, op: c4d.BaseObject,
                            bt: c4d.threading.BaseThread, priority: int, flags: int) -> int:
                    """Called when expressions are evaluated to let a tag modify a scene.
            
                    Does nothing in this example.
                    """
                    return c4d.EXECUTIONRESULT_OK
            
                def GetDDescription(self, node: c4d.GeListNode, description: c4d.Description, 
                                    flags: int) -> typing.Union[bool, tuple[bool, int]]:
                    """Called by Cinema 4D when the description of a node is being evaluated to let the node
                    dynamically modify its own description.
                    """
                    # Bail when the description cannot/is not fully loaded.
                    if not description.LoadDescription(node.GetType()):
                        return False, flags
            
                    singleId: c4d.DescID = description.GetSingleDescID()
                    for paramId, dataDictionary in DynamicDescriptionTagData.INTERFACE_DATA:
            
                        if (singleId and not paramId.IsPartOf(singleId)):
                            return True, flags
            
                        data: c4d.BaseContainer = description.GetParameterI(paramId)
                        if data is None:
                            return True, flags
            
                        for key, value in dataDictionary.items():
                            data[key] = value
                            print (f"{data[key]} ({key})")
            
                    return True, flags | c4d.DESCFLAGS_DESC_LOADED
            
            
            def RegisterPlugins() -> None:
                """Registers the plugins contained in this file.
                """
                if not c4d.plugins.RegisterTagPlugin(
                        id=DynamicDescriptionTagData.ID_PLUGIN,
                        str="DynDescription Tag",
                        info=c4d.TAG_EXPRESSION | c4d.TAG_VISIBLE,
                        g=DynamicDescriptionTagData, description="tdyndescription",
                        icon=c4d.bitmaps.InitResourceBitmap(c4d.ID_MODELING_MOVE)):
                    print("Warning: Failed to register 'DynDescription' tag plugin.")
            
            
            if __name__ == "__main__":
                RegisterPlugins()
            

            Resource

            // The description defintion of the tag Tdyndescription.
            CONTAINER Tdyndescription
            {
              NAME Tdyndescription;
              INCLUDE Texpression;
            
              // The main "Tag" tab of the tag.
              GROUP ID_TAGPROPERTIES
              {
                // A subcontainer, just to keep the example the same.
                GROUP ID_GRP_STUFF
                {
                  // Your two parameters, we will drive their min, max, and name valumes
                  // dynamically.
                  REAL ID_OFF_X { MIN -90.0; MAX 90.0; UNIT METER; STEP 0.005; CUSTOMGUI REALSLIDER; }
                  REAL ID_OFF_Y { MIN -90.0; MAX 90.0; UNIT METER; STEP 0.005; CUSTOMGUI REALSLIDER; }
                }
              }
            }
            
            #ifndef _TDYNDESCRIPTION_H_
            #define _TDYNDESCRIPTION_H_
            
            enum
            {
              ID_GRP_STUFF = 2000,
              ID_OFF_X = 1000,
              ID_OFF_Y,
            }
            
            #endif // _TDYNDESCRIPTION_H_
            
            STRINGTABLE Tdyndescription
            {
              Tdyndescription "DynDescription";
              ID_OFF_X "off.x";
              ID_OFF_Y "off.y";
            }
            

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 1
            • mocolocoM
              mocoloco
              last edited by

              Hi @ferdinand,

              Thanks a lot for your time on this and sorry for the wrong unit on the first example I submitted with METERS instead of DEGREES - at the sometime it seems that it raised some kind of bug link to this ^^.

              Like you wrote, I did convert the value in Radian for all the Parameters and so, but anyway the problem seems linked to the simultaneous use of UNIT DEGREES; CUSTOMGUI REALSLIDER in the resource file.

              I ran a couple of tests and I noticed the following:
              • When only using REAL without CUSTOMGUI REALSLIDER; in the resource file, the field behaves as it should and limits changes works as expected
              • When using CUSTOMGUI REALSLIDER; with UNIT METERS; it does work as well as expected
              • When using UNIT PERCENT; with MIN -100.0; MAX 100.0 and assigning the values by multiplying the slider value by Parameters[--max], printing and assigning the result to a STATICTEXTit displays the right value in degree or rad depending on the final conversion made prior display.
              • When assigning UNIT DEGREES; with CUSTOMGUI REALSLIDER, I'm getting weird behaviour like said previously and like you noticed.

              I haven't had the time to ran test today with INTERFACE_DATA like you suggested. I will try to do that tomorrow and I will keep you in touch about this.

              Cheers,
              Christophe

              ferdinandF 1 Reply Last reply Reply Quote 0
              • ferdinandF
                ferdinand @mocoloco
                last edited by ferdinand

                Hey @mocoloco,

                No need to be sorry. For UNIT PERCENT you will have to write values as decimal values, i.e., 100% is 1.0.

                The root problem is the weird behavior of MINSLIDERS and MAXSLIDERS not being written when messing with the description when the unit is percent. The best way to check for possible "tricks", would be to inspect a valid existing description for a REAL, UNIT DEGREE parameter to see what is what.

                And as stated in my last posting, I unfortunately will not have the time to debug this this week, but I will give it a spin next week.

                Cheers,
                Ferdinand

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 0
                • mocolocoM
                  mocoloco
                  last edited by

                  Hi @ferdinand,

                  I was quite sure indeed that UNIT PERCENT will work, but I give a try to see. What I do not understand is, when I'm printing all the values existing in desc_X or desc_Y, they looks good, the value is correct, but not took completely into account on the drawing side for CUSTOMGUI REALSLIDER.

                  Like I said, if I remove the CUSTOMGUI REALSLIDER; option in the resource file and using REAL as a standard input field, whatever the UNIT I'm using, everything behaves correctly. MIN/MAX values are correctly assigned even though there is multiple REAL that need to be change. That let me lead like you to a bug linked to CUSTOMGUI REALSLIDER when only using UNIT DEGREE.

                  No problem to have a look on this next week. I can deal with that for the moment using PERCENT, as is produce slightly the same result. It is just not really convenient to guess a percentage for an angle, but that's OK.

                  Many thanks,
                  Cheers,

                  Christophe

                  ferdinandF 1 Reply Last reply Reply Quote 0
                  • ferdinandF
                    ferdinand @mocoloco
                    last edited by ferdinand

                    Hey @mocoloco,

                    I had time to revisit this today with less time pressure than I had before. I made some mistakes in my prior answer:

                    • MINSLIDER and MAXSLIDER are being written even when the unit is DEGREE
                    • Being the first item or not in a group is irrelevant for the problem, the determining factor is if the new range is larger or smaller than the old one.
                    • When one overwrites an edit and slider range with a range that is larger than the old one, and the unit is degree:
                      • Both the edit and slider range remain the old value for the user when interacting with the GUI,
                      • But the position of the slider know on the slider bar reflects the new value, with the side effect that the user cannot drag the knob all the way, as the range is still clamped to the old values.
                      • And the description data that are stored reflect the new value.
                      • For any other unit other than DEGREE this does not happen.

                    You can see here the effect for the same plugin I used in my prior posting, where both parameters are initialized as [-90°, 90°]. The first one is then changed to [-45°, 45°] and the second one to [-180°, 180°]. The first parameter works fine, while the second one exhibits the effects described above with both the value and slider clamp range being unchanged while the slider position reflects the new value.

                    weird_stuff.gif
                    Fig. I: When the unit is DEGREE, increasing the value and slider range will fail. Also shown here, I compare the description of our modified bar.y parameter with a user data parameter of the same date type, unit, and range. The values are identical.

                    I also talked with one of our GUI developers and he does not see any problems with the code we use either. This is very likely a bug, since the data in the description is the same (bar.y and data.x in the example screen cast above and the print out below), but treated differently, when and only when the unit is DEGREE. I have filed an issue for that in our bug tracker.

                    I currently also do not see any good workaround for this for you. You will have to wait for a fix or the dev untangling the core issue and telling us how you can work around this. I have for now classified the issue as low priority, which means it might take some time before we get to it.

                    Cheers,
                    Ferdinand

                    The script to print out the description of the active tag I used in the example:

                    import c4d
                    import typing
                    
                    DESC_MAP: dict[int: str] = {
                        c4d.DESC_NAME: "DESC_NAME",
                        c4d.DESC_SHORT_NAME: "DESC_SHORT_NAME",
                        c4d.DESC_VERSION: "DESC_VERSION",
                        c4d.DESC_CHILDREN: "DESC_CHILDREN",
                        c4d.DESC_MIN: "DESC_MIN",
                        c4d.DESC_MAX: "DESC_MAX",
                        c4d.DESC_MINEX: "DESC_MINEX",
                        c4d.DESC_MIN: "DESC_MIN",
                        c4d.DESC_MAXEX: "DESC_MAXEX",
                        c4d.DESC_MAX: "DESC_MAX",
                        c4d.DESC_STEP: "DESC_STEP",
                        c4d.DESC_ANIMATE: "DESC_ANIMATE",
                        c4d.DESC_ANIMATE_MIX: "DESC_ANIMATE_MIX",
                        c4d.DESC_ASKOBJECT: "DESC_ASKOBJECT",
                        c4d.DESC_UNIT: "DESC_UNIT",
                        c4d.DESC_PARENTGROUP: "DESC_PARENTGROUP",
                        c4d.DESC_CYCLE: "DESC_CYCLE",
                        c4d.DESC_HIDE: "DESC_HIDE",
                        c4d.DESC_DEFAULT: "DESC_DEFAULT",
                        c4d.DESC_ACCEPT: "DESC_ACCEPT",
                        c4d.DESC_SEPARATORLINE: "DESC_SEPARATORLINE",
                        c4d.DESC_REFUSE: "DESC_REFUSE",
                        c4d.DESC_PARENTID: "DESC_PARENTID",
                        c4d.DESC_CUSTOMGUI: "DESC_CUSTOMGUI",
                        c4d.DESC_COLUMNS: "DESC_COLUMNS",
                        c4d.DESC_LAYOUTGROUP: "DESC_LAYOUTGROUP",
                        c4d.DESC_REMOVEABLE: "DESC_REMOVEABLE",
                        c4d.DESC_GUIOPEN: "DESC_GUIOPEN",
                        c4d.DESC_EDITABLE: "DESC_EDITABLE",
                        c4d.DESC_MINSLIDER: "DESC_MINSLIDER",
                        c4d.DESC_MAXSLIDER: "DESC_MAXSLIDER",
                        c4d.DESC_GROUPSCALEV: "DESC_GROUPSCALEV",
                        c4d.DESC_SCALEH: "DESC_SCALEH",
                        c4d.DESC_LAYOUTVERSION: "DESC_LAYOUTVERSION",
                        c4d.DESC_ALIGNLEFT: "DESC_ALIGNLEFT",
                        c4d.DESC_FITH: "DESC_FITH",
                        c4d.DESC_NEWLINE: "DESC_NEWLINE",
                        c4d.DESC_TITLEBAR: "DESC_TITLEBAR",
                        c4d.DESC_CYCLEICONS: "DESC_CYCLEICONS",
                        c4d.DESC_CYCLESYMBOLS: "DESC_CYCLESYMBOLS",
                        c4d.DESC_PARENT_COLLAPSE: "DESC_PARENT_COLLAPSE",
                        c4d.DESC_FORBID_INLINE_FOLDING: "DESC_FORBID_INLINE_FOLDING",
                        c4d.DESC_FORBID_SCALING: "DESC_FORBID_SCALING",
                        c4d.DESC_UNIT_METER: "DESC_UNIT_METER",
                        c4d.DESC_ANGULAR_XYZ: "DESC_ANGULAR_XYZ",
                        c4d.DESC_INPORT: "DESC_INPORT",
                        c4d.DESC_OUTPORT: "DESC_OUTPORT",
                        c4d.DESC_STATICPORT: "DESC_STATICPORT",
                        c4d.DESC_NEEDCONNECTION: "DESC_NEEDCONNECTION",
                        c4d.DESC_MULTIPLE: "DESC_MULTIPLE",
                        c4d.DESC_PORTONLY: "DESC_PORTONLY",
                        c4d.DESC_CREATEPORT: "DESC_CREATEPORT",
                        c4d.DESC_PORTSMIN: "DESC_PORTSMIN",
                        c4d.DESC_PORTSMAX: "DESC_PORTSMAX",
                        c4d.DESC_NOTMOVABLE: "DESC_NOTMOVABLE",
                        c4d.DESC_EDITPORT: "DESC_EDITPORT",
                        c4d.DESC_ITERATOR: "DESC_ITERATOR",
                        c4d.DESC_PARENTMSG: "DESC_PARENTMSG",
                        c4d.DESC_MATEDNOTEXT: "DESC_MATEDNOTEXT",
                        c4d.DESC_COLUMNSMATED: "DESC_COLUMNSMATED",
                        c4d.DESC_SHADERLINKFLAG: "DESC_SHADERLINKFLAG",
                        c4d.DESC_NOGUISWITCH: "DESC_NOGUISWITCH",
                        c4d.DESC_COLORALWAYSLINEAR: "DESC_COLORALWAYSLINEAR",
                        c4d.DESC_HIDE_WHEN_INLINE: "DESC_HIDE_WHEN_INLINE",
                        c4d.DESC_MATERIALEDITOR_LEFTSIDE: "DESC_MATERIALEDITOR_LEFTSIDE",
                        c4d.DESC_CHANGED: "DESC_CHANGED",
                        c4d.DESC_HIDEINFIELDS: "DESC_HIDEINFIELDS",
                        c4d.DESC_SHOWINFIELDS: "DESC_SHOWINFIELDS",
                        c4d.DESC_FIELDCOLORCHANNEL: "DESC_FIELDCOLORCHANNEL",
                        c4d.DESC_FIELDDIRECTIONCHANNEL: "DESC_FIELDDIRECTIONCHANNEL",
                        c4d.DESC_FIELDVALUECHANNEL: "DESC_FIELDVALUECHANNEL",
                        c4d.DESC_FIELDROTATIONCHANNEL: "DESC_FIELDROTATIONCHANNEL",
                        c4d.DESC_NODEPORT: "DESC_NODEPORT",
                        c4d.DESC_REPLACECOMPLEXUI: "DESC_REPLACECOMPLEXUI",
                        c4d.DESC_REPLACE_HIDE: "DESC_REPLACE_HIDE",
                        c4d.DESC_RESOURCEPATH: "DESC_RESOURCEPATH",
                        c4d.DESC_RESOURCELINE: "DESC_RESOURCELINE",
                        c4d.DESC_TEMPDESCID: "DESC_TEMPDESCID",
                        c4d.DESC_IDENT: "DESC_IDENT",
                        c4d.DESC_IDENT_ORIGIN: "DESC_IDENT_ORIGIN",
                        c4d.DESC_DISABLELAYOUTSWITCH: "DESC_DISABLELAYOUTSWITCH",
                        c4d.DESC_UNIMPORTANTFORDEFAULTS: "DESC_UNIMPORTANTFORDEFAULTS",
                    }
                    
                    op: c4d.BaseObject # The active object.
                    doc: c4d.documents.BaseDocument # The active document.
                    
                    def main():
                        """
                        """
                        tag: c4d.BaseTag = doc.GetActiveTag()
                        if tag is None:
                            return
                    
                        c4d.CallCommand(13957)
                        line: str = "{} = {}"
                        data: c4d.BaseContainer
                    
                        for data, _, _ in tag.GetDescription(c4d.DESCFLAGS_DESC_NONE):
                            print ("\n" + ("-" * 100) + "\n")
                            for did, label in DESC_MAP.items():
                                value: typing.Any = data[did]
                                if value is None:
                                    continue
                    
                                if isinstance(value, c4d.BaseContainer):
                                    print(line.format(label, ""))
                                    for k, v in value:
                                        print(f"\t{k}: {v}")
                                else:
                                    print(line.format(label, value))
                    
                    if __name__ == "__main__":
                        main()
                    

                    Output:

                    [...]
                    
                    ----------------------------------------------------------------------------------------------------
                    
                    DESC_NAME = foo.x
                    DESC_ANIMATE_MIX = foo.x
                    DESC_VERSION = 3
                    DESC_MIN = -0.7853981633974483
                    DESC_MAX = 0.7853981633974483
                    DESC_MINEX = 0
                    DESC_MAXEX = 0
                    DESC_STEP = 8.726646259971648e-05
                    DESC_ANIMATE = 1
                    DESC_UNIT = 1717856114
                    DESC_CUSTOMGUI = 1000489
                    DESC_MINSLIDER = -0.7853981633974483
                    DESC_MAXSLIDER = 0.7853981633974483
                    DESC_IDENT = ID_OFF_X
                    
                    ----------------------------------------------------------------------------------------------------
                    
                    DESC_NAME = bar.y
                    DESC_ANIMATE_MIX = bar.y
                    DESC_VERSION = 3
                    DESC_MIN = -3.141592653589793
                    DESC_MAX = 3.141592653589793
                    DESC_MINEX = 0
                    DESC_MAXEX = 0
                    DESC_STEP = 8.726646259971648e-05
                    DESC_ANIMATE = 1
                    DESC_UNIT = 1717856114
                    DESC_CUSTOMGUI = 1000489
                    DESC_MINSLIDER = -3.141592653589793
                    DESC_MAXSLIDER = 3.141592653589793
                    DESC_IDENT = ID_OFF_Y
                    
                    ----------------------------------------------------------------------------------------------------
                    
                    DESC_NAME = User Data
                    DESC_ANIMATE_MIX = User Data
                    DESC_DEFAULT = 1
                    DESC_IDENT = ID_USERDATA
                    
                    ----------------------------------------------------------------------------------------------------
                    
                    DESC_NAME = data.x
                    DESC_ANIMATE_MIX = data.x
                    DESC_VERSION = 3
                    DESC_MIN = -3.141592653589793
                    DESC_MAX = 3.141592653589793
                    DESC_MINEX = 0
                    DESC_MAXEX = 0
                    DESC_STEP = 8.726646259971648e-05
                    DESC_ANIMATE = 1
                    DESC_UNIT = 1717856114
                    DESC_PARENTGROUP = (700, 5, 0)
                    DESC_CUSTOMGUI = 1000489
                    DESC_REMOVEABLE = 1
                    DESC_EDITABLE = 1
                    DESC_MINSLIDER = -3.141592653589793
                    DESC_MAXSLIDER = 3.141592653589793
                    

                    MAXON SDK Specialist
                    developers.maxon.net

                    1 Reply Last reply Reply Quote 0
                    • mocolocoM
                      mocoloco
                      last edited by

                      Good morning @ferdinand,

                      Thanks a lot for taking time going though this. That's exactly what I noticed last week. Changed are took into account but they are not reflected on the GUI. The only workaround that seems possible at this moment is to set MIN/MAX sliders values beyond the possible values that could be set on UserData. Doing so GUI should behave correctly.

                      Could you please let this thread unsolved for the moment, the time we get a fix on this?

                      Have a great day,
                      Cheers,

                      ferdinandF 1 Reply Last reply Reply Quote 0
                      • ferdinandF
                        ferdinand @mocoloco
                        last edited by

                        @mocoloco said in Can REAL MIN / MAX value be changed on Init?:

                        Could you please let this thread unsolved for the moment, the time we get a fix on this?

                        Typically, we track to be fixed issues with the to fix tag which I have also added to your thread here. With that we know where to look once we fixed the issue to announce the fix. What would be the advantage of letting this topic unsolved for you? Youl will also get notified when there is a new reply in a solved topic, e.g., us announcing that we fixed something.

                        Cheers,
                        Ferdinand

                        MAXON SDK Specialist
                        developers.maxon.net

                        1 Reply Last reply Reply Quote 0
                        • mocolocoM
                          mocoloco
                          last edited by

                          Oh, I didn't know about the to fix tag. Keeping unsolved was much more for the community 😉
                          I the meantime I setup the resource file as discussed, and indeed, having higher values prior setting them solve the GUI problem / which is a good fix for me.

                          Thanks a lot,
                          Cheers,

                          Christophe

                          1 Reply Last reply Reply Quote 0
                          • maxonM maxon moved this topic from Cinema 4D SDK on
                          • mocolocoM
                            mocoloco
                            last edited by

                            Hi there,
                            Was the issue fixed on R2023 or R2024?

                            Thanks,
                            Christophe

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