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

    Sorting the OM using lists

    Scheduled Pinned Locked Moved PYTHON Development
    9 Posts 0 Posters 1.0k Views
    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.
    • H Offline
      Helper
      last edited by

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 22/07/2011 at 10:41, xxxxxxxx wrote:

      Python has really wonderful list sorting tools. So I want to take advantage of that to re-arrange objects in the OM based on attributes. Like object positions.
      But I can't quite figure it out.

      I can get as far as creating the sorted list like this:

      import c4d  
      from c4d import gui  
        
      def main() :  
        
        posYsorted = []                   #This will eventually hold the sorted Y vectors    
        sel = doc.GetActiveObjects(False) #Get the active objects  
        for i, obj in enumerate(sel) :     #Loop through the selected objects  
         pos = sel[i].GetAbsPos()         #Get their positions(all three vectors)  
         posY = pos.y                     #Get just the Y position vector now  
         posYsorted.append(posY)          #Add the Y position for each object to the list  
        posYsorted.sort()                 #Now sort the list   
        
        print posYsorted  
        
        #Now I have a sorted list to use: "posYsorted = []".  
        #How do I re-arrange the selected objects in the OM  
        #So they appear in the OM in the same order as the items in that sorted list?   
         
      if __name__=='__main__':  
        main()
      

      But now that I have that sorted list.
      I can't figure out how to re-arrange things in the OM to match my sorted list.

      Any ideas how to do this?

      -ScottA

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 22/07/2011 at 12:55, xxxxxxxx wrote:

        Hey Scott,

        I would copie and delete the old ones and insert them new into the om.

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 22/07/2011 at 15:25, xxxxxxxx wrote:

          I was hoping to avoid doing that.
          I've been desperately trying to learn how to sort things in the OM( other than by their name) with Python lists. And I keep hitting a brick wall.

          I accidentally discovered a method to sort things with coffee using the built-in "object" keyword:

          arrangeByYpositionForward()                 //Our splines might be created out of order. So this orders them by their Y positions  
          {  
          var doc = GetActiveDocument();  
          var numSelected = 0;  
          while (object(numSelected)) numSelected++; // count selected elements  
          var sel = new(array,numSelected);   
          var i=0;  
          while (i < numSelected)  
            {  
            sel[i] = object(i);        
            var pos = sel[i]->GetAbsPos();  
            if(sel[i]->GetNext())  
             {  
              var next = sel[i]->GetNext();  
              var npos = next->GetPosition();  
              if(pos.y < npos.y)  
                {           
                 next->Remove();  
                 doc->InsertObject(next,null,null);  
                }  
              }        
            i++; // Increment i so loop knows how many time to run  
          }  
          }  
            
            
          arrangeByYpositionReverse()             //Our splines might be created out of order. So this orders them by their Y positions  
          {  
          var doc = GetActiveDocument();  
          var numSelected = 0;  
          while (object(numSelected)) numSelected++; // count selected elements  
          var sel = new(array,numSelected);   
          var i=0;  
          while (i < numSelected)  
            {  
            sel[i] = object(i);        
            var pos = sel[i]->GetAbsPos();  
            if(sel[i]->GetNext())  
             {  
              var next = sel[i]->GetNext();  
              var npos = next->GetPosition();  
              if(pos.y > npos.y)  
                {           
                 next->Remove();  
                 doc->InsertObject(next,null,null);  
                }  
              }        
            i++; // Increment i so loop knows how many time to run  
          }  
          }
          

          And I cannot figure out how to do this same kind of thing with Python.

          This coffee code is from my script: EdgesToJoints
          The coffee version works really good at converting them in BOTH directions.
          But my Python version has all kinds of weird problems. Because I can't figure out how to replicate what I did in coffee. I discovered it by accident.

          I really, really need to learn how to sort items in the OM. Relative to their positions(not by names) with Python lists.
          It seems that I'm always needing the ability to do that kind of OM sorting and re-arranging.

          -ScottA

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 22/07/2011 at 19:16, xxxxxxxx wrote:

            Hey scott! i hope this maybe helps you out. A little while ago i did a similar test python generator that sorts its children by y position. Basically i just store and sort the positions and then i use another for...in... statement to go through the list and compare each objects y position to each value in the list and sort them accordingly. hope it helps, I owe you one for helping me out so many times!

            here is the scene file

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 22/07/2011 at 22:54, xxxxxxxx wrote:

              ____Thanks for the file. But I'm afraid it still doesn't solve what I'm trying to solve.
              The answer might be in there. And I'm not seeing it.

              Try out this coffee code on some objects spread acrosses the X axis:

              arrangeByXpositionForward() //Arrange objects by their X positions  
              {  
              var doc = GetActiveDocument();  
              var numSelected = 0;  
              while (object(numSelected)) numSelected++; // count selected elements and increment numSelect  
              var sel = new(array,numSelected); // Create a new array with numSelected number of elements in it  
              var i=0;  
              while (i < numSelected)  
                {  
                sel = object(i);       
                var pos = sel->GetAbsPos();  
                if(sel->GetNext())  
                 {  
                  var next = sel->GetNext();  
                  var npos = next->GetPosition();  
                  if(pos.x > npos.x)  
                    {          
                     next->Remove();  
                     doc->InsertObject(next,null,null);  
                    }  
                  }       
                i++; // Increment i so loop knows how many time to run  
              }  
              }  
                
              main(doc,op)  
              {  
               arrangeByXpositionForward();  
              }
              

              It will re-arrange the objects in the OM based on their X positions. Not their names.
              And not only that. If you swap: if(pos.x > npos.x) with: if(pos.x < npos.x) It will arrange them in reverse in the OM.

              No matter what I try in Python. I can't replicate this same result I'm getting with Coffee.
              It's like black magic Vodoo. I don't know how it's doing it.😲

              -ScottA


              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 23/07/2011 at 02:43, xxxxxxxx wrote:

                Hi Scott,
                 
                In Python, I'd just use the built in sorting algorithm.
                Cheers,
                 
                PS: The coffee code is a little bit buggy 😉
                 
                 
                [edit]
                Something like this:

                 **import** c4d
                **def** GetHighest(doc) :  
                    op = doc.GetFirstObject()  
                    **while** op:  
                        **yield** op  
                        op = op.GetNext()
                **def** Sort(objects) :  
                    objects = list(objects)  
                    **for** op **in** objects:  
                        op.Remove()  
                    objects.sort(key = **lambda** x: x.GetAbsPos().x)  
                    **for** op **in** objects:  
                        doc.InsertObject(op)  
                    **return** objects
                Sort(GetHighest(doc))
                
                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 23/07/2011 at 07:42, xxxxxxxx wrote:

                  Thanks Nux,

                  That does look like kind of thing I'm looking for. Do you know how to reverse the sort order with this?
                  I need to be able to sort things in both directions.

                  I tried using objects.reverse() and changing GetNext() to GetPred(). But I couldn't get it to work.

                  -ScottA

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 23/07/2011 at 07:48, xxxxxxxx wrote:

                    objects.sort(key = lambda x: x.GetAbsPos().x, reverse = True)
                    

                    or you use the builtin reversed - function.

                    objects = list(reversed(objects))
                    

                    Cheers,
                    Niklas

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 23/07/2011 at 07:59, xxxxxxxx wrote:

                      Nice.
                      This is one area where Python really shines.

                      Thanks for the help. 🍺

                      -ScottA

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