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

    What is the max parameter in BaseSelect.GetRange() really for?

    Cinema 4D SDK
    r21 python
    4
    7
    1.1k
    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.
    • CairynC
      Cairyn
      last edited by

      As the headline says...BaseSelect.GetRange() returns the min and max values for a segment in a selection. But it has a second parameter (besides the segment), called max.

      Now, max is not needed from a structural point of view. The selection contains a known number of segments, which contain one tuple each. Other than e.g. BaseSelect.SelectAll(), where we actually need to pass a max value because the BaseSelect does not know the total number of elements that may possibly selected, GetRange() does not deal with unknowns.

      The documentation says about this parameter:

      max (int) –
      The maximum value for the returned elements numbers.
      Usually pass PolygonObject.GetPolygonCount() or PointObject.GetPointCount() or the edge count of the object.
      The method makes sure they are < max.
      

      I would interpret that as assurance that any value we get returned is smaller than max. So if there is a segment (1,5) and max = 3, then we'd get (1,3) back. (I can't for the life of me think of a reason why I would want that, but hey.)

      That is, however, not what I really get. If I use a value for max that is smaller than the value GetRange tries to return, I receive TypeError: 'NoneType' object is not iterable. If I use a ridiculous large value for max, no apparent effects happen at all, not even a perceivable increase in runtime.

      So, I have a parameter that at best does nothing, and at worst throws an error. I don't know whether this is a bug (R21) or whether I just don't understand the function.

      The C++ doc says about the same parameter:

      The maximum value for a and b. Makes sure a and b are < maxElements. Pass LIMIT<Int32>::MAX for no additional checks.
      

      That supports my understanding of the parameter, but does not explain why I get a TypeError instead.
      (It also doesn't explain why a limit on the selection is so important that it justifies an additional parameter when the check could easily be done on the returned values. Or: what happens, if both returned limits of the segment are larger than max.)

      btw, it would be nice if the Python docs also contained the additional info from the C++ doc:

      The spans are always sorted (spans with higher index have higher numbers for a/b), also b is always >= a. 
      
      P 1 Reply Last reply Reply Quote 0
      • P
        PluginStudent @Cairyn
        last edited by

        @Cairyn said in What is the max parameter in BaseSelect.GetRange() really for?:

        I would interpret that as assurance that any value we get returned is smaller than max. So if there is a segment (1,5) and max = 3, then we'd get (1,3) back. (I can't for the life of me think of a reason why I would want that, but hey.)

        Simple: interpret an element number as an index. You don't want that index to be out of range.

        If you have a list of n elements and a BaseSelect object to store which elements of that list are "selected", you want to ensure that an index provided by GetRange() is a valid index of that list.

        Why there is an issue with Python I don't know.

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

          Hi,

          I admittedly do not quite understand what @PluginStudent is trying to convey here, so I might be misunderstanding something about your question.

          As your quoted description says, the method will test internally that a and b are smaller than max. If they do not match this criteria, this method fails and returns None. I am not quite sure where you would need that, but the scenario would be that you expect a segment not to surpass a certain index and want to test that. You could of course also just test the returned tuple, so it is not very useful. Probably some weird internal reason.

          About your error, are sure that actually the method is raising the error and not your surrounding code with an unpacking or indexing operation for example? When the return value is None, that would give you exactly that error. E.g. this will fail when the method fails, i.e. returns None:

          a, b = selection.GetRange(*data)
          

          Cheers,
          zipit

          MAXON SDK Specialist
          developers.maxon.net

          CairynC 1 Reply Last reply Reply Quote 1
          • CairynC
            Cairyn @PluginStudent
            last edited by

            @PluginStudent But the indices in the segment in the BaseSelect are automatically valid if the BaseSelect was built by a valid source. The only way to get invalid values would be to apply the same BaseSelect to a different object with less polys/points, and in that case the function GetRange() is of lower priority - you'd get out of range errors much earlier.

            If you really have an arbitrary BaseSelect to store indices from a list, and the BaseSelect contains indices that are not in the list at all, then your code is buggy, and limiting the output of GetRange() would be just covering up that bug.

            It's confusing. Maybe it's just a relic from some older code, grandfathered into the current API.

            1 Reply Last reply Reply Quote 0
            • CairynC
              Cairyn @ferdinand
              last edited by

              @zipit said in What is the max parameter in BaseSelect.GetRange() really for?:

              About your error, are sure that actually the method is raising the error and not your surrounding code with an unpacking or indexing operation for example? When the return value is None, that would give you exactly that error. E.g. this will fail when the method fails, i.e. returns None:

              a, b = selection.GetRange(*data)
              

              Aha, good thinking! Yes, that's exactly the error.

              The doc for the parameter doesn't say that the function completely fails when the max condition is not met - it just states The method makes sure they are < max.
              That of course also answers my question what happens when a and b both are < max. It makes the existence of the parameter even more mysterious, but it explains why I get this error.

              I definitely need to be more careful with return value checking... thanks!

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

                hi,

                honestly i didn't found any places that could be useful.

                The fact is that you can use Select with any kind of number even if it is superior to the number of polygon, point or edge your object is composed of.

                BaseSelect is also used to know witch text is selected (on parameter). But even there, i got doubt that this Max parameter is usefull.

                It just save you time to not check if the value aren't superior to what's possible.

                and thanks again @zipit

                Cheers,
                Manuel

                MAXON SDK Specialist

                MAXON Registered Developer

                1 Reply Last reply Reply Quote 0
                • CairynC
                  Cairyn
                  last edited by

                  yupyup, BaseSelect has no connection to the original object it actually selects from, not even in the cases where you get a pointer to the BaseSelect returned and change the selection directly through it.

                  That's why we need the max parameter for SelectAll and ToggleAll -- the BaseSelect doesn't know what "all" even is. (Not GetLastElement()!) For GetRange() though, that reasoning does not apply.

                  Now let's see whether I can crash C4D with inconsistent edge selections...

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