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

    Delete points based on distance

    Cinema 4D SDK
    python
    3
    13
    2.9k
    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.
    • A
      andmotion @s_bach
      last edited by

      Hey Sebastian,

      It's sound for me really complicated 🙂
      What I would like to achieve is this :

      • Based on the distance between two object, remove points from the object_1 while the object_2 is close enough to the object_1.

      • Would that be possible in Xpresso and its point node?

      Thanks again for your input.
      Thanks,
      Andrzej

      1 Reply Last reply Reply Quote 0
      • A
        andmotion
        last edited by

        Hey zipit,

        Thanks for your suggestions.
        I am coming from vex Houdini so I can picture the code here how I can get this type of effect in Houdini I know it's not relevant to C4D but I am trying to make this simple effect in C4D.

        In H it would be like this :

        • I have sphere as a obj_01, lets assume 100 points
        • I have one single point somewhere in obj space
        • I am taking the @P attributes of the points from obj_01 so I know now position of each point from obj_01
        • I am taking the @P attrib of the single point
        • Now when I know both vectors I can easily say this :
          -- if the pos of ONE POINT is close enough POINTS from obj_01
          delete those POINTS from the obj_01

        Hope that make sense:)
        I did never script in c4d so I can not post here any examples:(
        Ta

        1 Reply Last reply Reply Quote 0
        • S
          s_bach
          last edited by

          @andmotion The question is what kind of user interaction do you have in mind. As far as I can see, the Point operator in Xpresso does not allow to delete points.

          If a simple script is good enough, the desired effect of deleting points in a given radius is not that complicated. This is the code for a script executed in the Script Manager:

          import c4d
          
          
          def main():
              
              # get null object by name
              nullObj = doc.SearchObject("null")
              # get polygon object by name
              polyObj = doc.SearchObject("polygon")
              
              if nullObj is None:
                  return
              if polyObj is None:
                  return
              
              # get world space position of null object
              nullObjPos = nullObj.GetMg().off
              
              # get world space matrix and points of the polygon object
              mg = polyObj.GetMg()
              points = polyObj.GetAllPoints()
              
              # prepare the point selection of the polygon object
              selection = polyObj.GetPointS()
              selection.DeselectAll()
              
              # check each point
              for idx, point in enumerate(points):
                  
                  # get world space position of the point
                  pointPos = mg * point
                  
                  # get the distance from the point to the null object
                  diff = pointPos - nullObjPos
                  distance = diff.GetLength()
                  
                  # check distance
                  if distance < 100:
                      selection.Select(idx)
                      
              # delete selected points
              mode = c4d.MODELINGCOMMANDMODE_POINTSELECTION   
              res = c4d.utils.SendModelingCommand(c4d.MCOMMAND_DELETE, list = [polyObj], doc = doc, mode = mode)
              
              c4d.EventAdd()
                      
          if __name__=='__main__':
              main()
          

          MAXON SDK Specialist

          Development Blog, MAXON Registered Developer

          A 1 Reply Last reply Reply Quote 2
          • A
            andmotion
            last edited by

            @s_bach
            Thanks for the quick reply.
            That's is simply awesome that you made this code so I can dive in and actually grasp some python basic.

            I noticed that also yesterday, Xpresso wont allow me to delete points, I can iterate thru them but I could find the way how to literally delete it.

            Will go thru the code and let you know my thoughts, for now THANKS A LOT for help.
            Thanks

            1 Reply Last reply Reply Quote 0
            • A
              andmotion @s_bach
              last edited by

              @s_bach

              While trying to understand your code some questions raised in my head :

              1. polyObj.GetAllPoints(). Is it not each point vector? If it's I don't
                understand the idea of looping thru those vectors to get each pointPos.....

              2. It's hard for me also to pick up the idea of calculation pointPos
                inside the for loop. In your code you are multiplying polyObj global Matrix with point.....

              At the moment if I have both null and Sphere at 0,0,0 coordinates all points are deleted. if I move sphere a few units in Y axis strangely the middle of the sphere get deleted.

              I will spend more time on it to find out the solution. It seems like I will need some kind of channel(slider) while doing if distance < 100 so I could specified the radius by the slider.

              I would also need to have this distance updated in real time so when I move null close to the sphere in the viewport the points inside the radius are automatically deleted.

              I am really appreciated Sebastian your input here...Thanks

              1 Reply Last reply Reply Quote 0
              • A
                andmotion
                last edited by Manuel

                Here is the code I am playing with now

                import c4d
                from c4d import gui
                from c4d import utils
                
                #Welcome to the world of Python
                
                
                def main():
                    
                    
                    nullObj =  doc.SearchObject("Null")
                    polyObj = doc.SearchObject("Sphere")
                    
                    if nullObj:
                        print("Null is")
                        
                    if not nullObj:
                        print("no Null")
                        
                    if polyObj:
                        print("Sphere is")
                        
                    if not polyObj:
                        print("no Sphere")
                        
                    #get nullObj world space position
                    nullWSMg = nullObj.GetMg().off
                    print nullWSMg
                    
                    #get matrix and points from polyObj
                    polyObjWSMg = polyObj.GetMg().off
                    polyObjPointsPos = polyObj.GetAllPoints()
                    #print polyObjPointsPos
                    print polyObjWSMg
                    
                    #point selection of the polygon object
                    selection = polyObj.GetPointS()
                    selection.DeselectAll()
                    
                    #check each point
                    
                    for i, point in enumerate(polyObjPointsPos):
                        #get WS pos of the points
                        pointPos = polyObjWSMg * point
                        
                        #get the distance from point to the null
                        diff = nullWSMg - pointPos
                        distance = diff.GetLength()
                        
                        #check distance
                        if distance < 100:
                            selection.Select(i)
                            
                    #delete selected points
                    
                    mode = c4d.MODELINGCOMMANDMODE_POINTSELECTION
                    res = c4d.utils.SendModelingCommand(c4d.MCOMMAND_DELETE, list = [polyObj], doc = doc, mode = mode)
                            
                    c4d.EventAdd()
                    
                        
                if __name__=='__main__':
                    main()
                
                
                
                
                1 Reply Last reply Reply Quote 0
                • A
                  andmotion
                  last edited by

                  Here I uploaded the effect I am after :

                  I know that using Boole in C4D I can have exactly the same effect BUT my goal is to start from this simple effect as a python journey.
                  Thanks for any suggestion.
                  Thanks

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

                    Hi,

                    @andmotion said:

                    #get matrix and points from polyObj
                    polyObjWSMg = polyObj.GetMg().off
                    

                    You did not assign a matrix topolyObjWSMg but the offset vector off the global matrix of polyObj.

                    @andmotion said:

                    pointPos = polyObjWSMg * point
                    

                    Which will make pointPos here not a c4d.Vector but a float - the dot product of two vectors. You also don't have to calculate the global point positions in your loop if you find that distracting, you can just do:

                    mg = polyObj.GetMg()
                    global_points = [mg * p for p in polyObj.GetAllPoints()]
                    
                    distance_squared = 100 ** 2
                    null_mg = null.GetMg()
                    for pid, point in enumerate(global_points):
                        if (null_mg * point).GetLengthSquared() < distance_squared:
                            selection.Select(pid)
                    

                    And regarding odd behaviour and want you want to do, I would point to my first post. Still sounds to me you actually want to evaluate a gradient.

                    Cheers
                    zipit

                    MAXON SDK Specialist
                    developers.maxon.net

                    1 Reply Last reply Reply Quote 0
                    • S
                      s_bach
                      last edited by

                      Hello,

                      PointObject.GetAllPoints() returns a list of vectors; each vector is the object space position of the point of the corresponding index.

                      To get the world space position, you have to multiply that object space position with the world space matrix.

                      You find some information on matrix calculations here: Matrix Fundamentals.

                      If you want to have an interactive slider, you cannot use a script anymore. You have to write a plugin.

                      As described above, the best way would be to implement the functionality as a ObjectData based generator. This way a procedural workflow could be maintained.

                      Best wishes,
                      Sebastian

                      MAXON SDK Specialist

                      Development Blog, MAXON Registered Developer

                      1 Reply Last reply Reply Quote 0
                      • A
                        andmotion
                        last edited by

                        I thing after short research that c4d.plugins.ObjectData could actually be the solution I am after.
                        I will be posting my progress here.
                        Once again Thanks Guys for heads up!!!!!
                        Thanks

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