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

    How to get all elements from BaseSelect

    Cinema 4D SDK
    2
    3
    573
    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.
    • orestiskonO
      orestiskon
      last edited by

      Hello,
      I'm trying to get the selected points from an object. GetPointS gives a baseselect so I'm trying to retrieve the selected points' indices from the baseselect.

      In the attached example, I selected a few of the points of the cube. I iterate through all the baseselect ranges but only half of them give points. The other half result "None". Any idea why it isn't working and/or how to fetch the point selection without iterating through all the points of the object?

      # Main function
      def main():
          objectSelection = doc.GetActiveObject()
          pointSelection = objectSelection.GetPointS()
          selectedCount = pointSelection.GetCount()
          
          for segment in range(pointSelection.GetSegments()):
              print(pointSelection.GetRange(segment, selectedCount))
      

      baseselect.c4d

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

        Hi @orestiskon,

        thank you for reaching out to us. The problem with your code is that you pass the number of selected elements as the second argument to BaseSelect.GetRange(). But the method actually does expect the maximum index there, i.e., the total number of points for a point selection. While this method via .GetRange() is a bit more performant, in Python you can also use .GetAll() and list comprehensions. For details see the attached example.

        Cheers,
        Ferdinand

        """A simple example for how to iterate over point selections.
        
        As discussed in:
            https://developers.maxon.net/forum/topic/13115
        """
        
        import c4d
        
        
        def main():
            """Iterates over the selected objects and accesses their point selection.
            """
            # Iterate over the selected objects.
            for obj in doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE):
                # Step over non-point objects.
                if not isinstance(obj, c4d.PointObject):
                    continue
        
                # All the points of the point object.
                points = obj.GetAllPoints()
                # And their count.
                pointCount = obj.GetPointCount()
                # The point selection.
                selection = obj.GetPointS()
        
                # The selection state of all elements in the BaseSelect. This is
                # a list of booleans, e.g., [True, False, False, False] for a polygon
                # object with just one quad and the first point in it being
                # selected.
                state = selection.GetAll(pointCount)
                # We have to manually convert this to indices.
                indices = [eid for eid, value in enumerate(state) if value]
                # I.e., you can get all selected indices like this in one go:
                # [eid for eid, val in enumerate(selection.GetAll(pointCount)) if val]
        
                # Print some stuff out.
                print("Object:", obj.GetName())
                print("Indices of selected points:", indices)
                print("The corresponding points:", [points[i] for i in indices])
                # The number of selected elements in the selection.
                print ("selection.GetCount():", selection.GetCount())
                # The segments in the selection, this has nothing to do with the
                # topology, but is rather the number of consecutive selection index
                # "strips". E.g.: [True, True, False, True, True] would be two
                # segments.
                print ("selection.GetSegments():", selection.GetSegments())
                # You can also access the selected elements like you tried to.
                for segment in range(selection.GetSegments()):
                    # But you have to pass in here the point count, i.e., the number
                    # of total total possible indices, not the number of selected
                    # elements.
                    print(selection.GetRange(segment, pointCount))
                print("-"*79)
        
        
        if __name__ == '__main__':
            main()
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 2
        • orestiskonO
          orestiskon
          last edited by

          Thanks @ferdinand , I misinterpreted the GetRange argument. That clears it up, and thanks for the example as well, it's very useful!

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