Sorting the OM using lists



  • 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



  • 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.



  • 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



  • 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



  • 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




  • 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))
    


  • 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



  • 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



  • 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


Log in to reply