Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    BaseContainer Sort broken?

    Cinema 4D SDK
    python
    2
    7
    987
    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.
    • M
      mp5gosu
      last edited by mp5gosu

      I noticed a weird behvaior on a BC's Sort method. See below.

      import c4d
      
      
      if __name__=='__main__':
          items = {0: "a", 1: "b", 2: "c", 3:"d"}
          bc = c4d.BaseContainer()
          
          for x in items.items():
              bc.SetString(x[0], x[1])
          
          bc.Sort()
          for x in bc:
              print (x)
              
      

      This prints out the wrong order:

      (1, 'b')
      (0, 'a')
      (2, 'c')
      (3, 'd')
      

      Smells like a bug?

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

        Hi @mp5gosu,

        thank you for reaching out to us and thank you for pointing out this behaviour. However, this is not a bug, but an intentional feature which is linked to the fact the sub-menu titles will be stored under the ID 1 in a BaseContainer. Because of that the method will not be fixed and it is also very unlikely that we will update the documentation, as explaining the reason for this behaviour would require revealing more of the non-public API than we are currently comfortable with.

        However, since this is an intentional behaviour, you can rely on the fact that this will only happen with the ID 1. I.e., when you place your BaseContainer IDs in the range [1, +MAX_INT32], the sort method should work like intended.

        Thank you for your understanding,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • M
          mp5gosu
          last edited by

          Okay, thanks for the explanation.
          Although it makes sense in this particular context, I see a problem there regarding the general purpose of BaseContainers, since they are widely used.

          Would it be possible for future API updates to at least provide an optional parameter that the sorting will be in logical order?
          Like bc.Sort(natural_range=True) or something like that?

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

            Hi @mp5gosu,

            I can ask, but I doubt that this will added, because it is ultimately something that can be "fixed" relatively easily from the user side (see end of posting for example). The only meaningful explanation I can give is that BaseContainer.Sort was implemented for a very specific reason. BaseContainer is not really meant to be a replacement for a sortable collection data type.

            Cheers,
            Ferdinand

            """A little workaround for the somewhat odd BaseContainer sorting behavior.
            """
            
            import c4d
            
            def cleanSort(bc):
                """A little helper for BaseContainer.Sort().
                """
                # Sort the container.
                bc.Sort()
                # Get out when the IDs 0 and 1 are not of type string.
                if (bc.GetType(0) != c4d.DA_STRING or
                    bc.GetType(1) != c4d.DA_STRING):
                    return bc
                # Save the value of ID 1
                valIdOne = bc[1]
                # Remove the ID 1 and reinsert it in the "right" place.
                if bc.GetIndexId(0) == 1 and bc.RemoveIndex(0):
                    bc.InsDataAfter(1, valIdOne, bc.GetDataPointer(0))
                return bc
            
            def main():
                """
                """
                data = {3: "d", 1: "b", 2: "c", 0:"a"}
                bc = c4d.BaseContainer()
                for eid, value in data.items():
                    bc.SetString(eid, value)
            
                print ("Before:")
                for eid, value in bc:
                    print(f"id: {eid}, value:{value}")
                print ("")
            
                bc = cleanSort(bc)
            
                print ("After:")
                for eid, value in bc:
                    print(f"id: {eid}, value:{value}")
            
            
            if __name__=='__main__':
                main()
            

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • M
              mp5gosu
              last edited by

              Hehehe, thanks ferdinand.
              Really appreciate your effort.
              But in this case, I'll go for the 1st based indexing. Not a big deal.

              Thanks again! 🙂

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

                Hi @mp5gosu,

                I am sorry to inform you that we talked about the issue, implementing an overloaded version of BaseContainer::Sort, and decided that this is not something we want to do in the near future and probably also not at all.

                Cheers,
                Ferdinand

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 1
                • M
                  mp5gosu
                  last edited by mp5gosu

                  That's okay, since it is a minor issue.
                  For newcomers however, there should be a hint in the docs, because it clearly states Sorts the container entries by ID. which is not the case.

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