Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

[MEL] Ordering a list by order in outliner

[MEL] Ordering a list by order in outliner

Anonymous
Not applicable
6,149 Views
17 Replies
Message 1 of 18

[MEL] Ordering a list by order in outliner

Anonymous
Not applicable

Hello again community,

 

I've got a simple problem. I'm trying to apply some manipulations to a list of objects selected. So I've got something like:

 

string $array[] = `ls -sl`;
$numInts = size($array);
int $i=0;
for ($i=0;$i>$numInts;$i++)
{
setAttr ($array[1] + ".translateZ") (35 + $i*5);
}

 

and I need the list to be in the outliner order. How can I acheive that with MEL? 

 

Thank You

0 Likes
Accepted solutions (1)
6,150 Views
17 Replies
Replies (17)
Message 2 of 18

rajasekaransurjen
Collaborator
Collaborator

hi,

 

Try this.

 

string $array[] = `ls -sl -dag`;
int $i;
for ($i=1;$i<=size($array);$i++)
{
    setAttr ($array[$i] + ".translateZ") (35 + $i*5);
}

 

 

Hope this will help.

 

Best Regards,

Rajasekaran Surjen.

0 Likes
Message 3 of 18

Anonymous
Not applicable

Thanks a lot,

 

So the "-dag" flag is sorting the list, is that so?

0 Likes
Message 4 of 18

rajasekaransurjen
Collaborator
Collaborator

-dag flag list the Dag objects in the scene as in the outliner. With -sl flag it List Dag objects of selected object.

If you select a group or parent and use the flag -dag it list the dag objects in the selected group or parent.

It is not sorting the list.

0 Likes
Message 5 of 18

Anonymous
Not applicable

Ok thank you, but so it's not really helping for my current problem.

0 Likes
Message 6 of 18

rajasekaransurjen
Collaborator
Collaborator

OK..... explain your problem

0 Likes
Message 7 of 18

Anonymous
Not applicable

Well I'm opening some drawers from a furniture by script. But each drawer is opened a little bit more than the previous one. So in order for this to work, I need the script to select the drawers in the right order so the first one is open at let's say a translate of 20, the second one a translate of 25, etc.

 

I've tried adding the "-dag" flag tho, but it completely broke my selection so it doesn't seem to work for me.

 

 

0 Likes
Message 8 of 18

mspeer
Consultant
Consultant

Hi!

 

Simply select the objects in Outliner in the right order and run the script.

You can also create a Set for easy re-selection (also multiple Sets with different orders are possible).

0 Likes
Message 9 of 18

Anonymous
Not applicable

Hello, thx for the reply. I can't manually do the selection, The script has to do all of the job from the start to the end by himself. I'm using it for a lot of scenes and it's will process all of them one by one afterward.

0 Likes
Message 10 of 18

rajasekaransurjen
Collaborator
Collaborator

If you keeping the drawers in a order in outliner the -dag flag will work correctly. Keep the drawers in a separate group with a order it will work. If you can share the file and script.

0 Likes
Message 11 of 18

Anonymous
Not applicable

Sorry but as I said, this solution doesn't work for me.

 

When I tried, it destroyed all my previous selection and the script wasn't acting on the right objects. And the Drawers aren't always in the same hierarchy level in some of the files. Unfortunately, I can't share the files with you, as it's under a work project. However, I can write you the full selection and working process in this script:

 

 

$l=`ls`;

 

//Select "drawer_GRP"
select -cl;
for ($item in $l)
{
   if (gmatch ($item, "*drawer_GRP") || gmatch ($item, "*drawer_GRP[0-9]"))
   {
      select -add $item;
   }
};

 

for ($item in $l)
{
   if (gmatch ($item, "*FAKE_drawer_GRP*"))
   {
      select -d $item;
   }
};

 

//Open drawers
string $array[] = `ls -sl`;
$numInts = size($array);
int $i=0;
for ($i=0;$i<$numInts;$i++)
{
   setAttr ($array[$i] + ".translateZ") (25 + $i*8);
}

0 Likes
Message 12 of 18

rajasekaransurjen
Collaborator
Collaborator

Are you selecting more then one drawer_GRP and running the script?

0 Likes
Message 13 of 18

Anonymous
Not applicable

I repeat but I'm not selecting anything manually, as showed in the script I've shared the script select himself the "drawer_GRP". But yes, some furniture has more than one.

0 Likes
Message 14 of 18

RFlannery1
Collaborator
Collaborator
Accepted solution

I think rajasekaransurjen may be right about the "-dag" flag, but it is being used in the wrong place.  Try adding it to your first call to "ls" instead of to the second.

// Use the -dag flag here
$l=`ls -dag`;

// Do not use the -dag flag here
string $array[] = `ls -sl`;
0 Likes
Message 15 of 18

Anonymous
Not applicable

Oh ok, thx to both of you!

0 Likes
Message 16 of 18

rajasekaransurjen
Collaborator
Collaborator

Hi,

This may help.

 

 

 

string $rsDrawer_GRP[] = `ls -sl`;
int $j;

for($j=0;$j<size($rsDrawer_GRP);$j++)
{
    string $array[] = `listRelatives  -c $rsDrawer_GRP[$j]`;
    float $rsList[];
    int $i,$k,$l,$m;
    $m=size($array);
    for ($i=0;$i<size($array);$i++)
    {
        vector $rsObjPos;
        $rsObjPos = `xform -q -ws -a -rp $array[$i]`;
        float $rsObjYPos = $rsObjPos.y;
        floatArrayInsertAtIndex( $i, $rsList, $rsObjYPos );
    }
    $rsList = `sort $rsList`;
    print $rsList;
    for($k=0;$k<size($rsList);$k++)
    {
        for($l=0;$l<size($array);$l++)
        {
            vector $rsObjPosn;
            $rsObjPosn = `xform -q -ws -a -rp $array[$l]`;
            float $rsObjYPost = $rsObjPosn.y;
            if($rsObjYPost == $rsList[$k])
            {
                print ("\n"+$array[$l]);
                print ("\n"+$rsList[$k]);
                print ("\n"+$l);
                $m=$m-1;
                setAttr ($array[$l] + ".translateZ") (35 + $m*5);
            }
        }
    }
}

0 Likes
Message 17 of 18

wynandlens
Enthusiast
Enthusiast

# Here is an elegant solution to arrange a list in a hierarchial order. I'm assuming its a list of joints, but any transform #will work.

# First get the parent joint in the list. (list is 'jnts')

parent_jnt = cmds.ls(jnts[0], l=1)[0].split('|')[1]

# Get all the children of the parent joint in reverse order

all_ordered_jnts = cmds.ls(cmds.listRelatives(parent_jnt, ad=1), parent_jnt)

# Reverse the order to get them in proper order

all_ordered_jnts.reverse()

# If the jnt is in the original list, then add it

ordered_jnts = []

for jnt in all_ordered_jnts:

    if jnt in jnts:

         ordered_jnts.append(jnt)

0 Likes
Message 18 of 18

Kahylan
Advisor
Advisor

Hi!

 

I know this thread is old, but since it has been recently bumped, I thoght I'd add some useful information.

 

The outliner is sorted by scene hierarchy, which is the same order that the ls command has on default. so here is how to get the ordered scene hierarchy:

//gets every object in scene
string $all[] = `ls -l`;
//gets only dag objects in scene
string $dag[] = `ls -dag -l`;
//gets only transforms
string $trans[] = `ls -dag -tr -l`

 

now if you have a random selection and you want to order it to fit the scene hierarchy, you simply need to check the names from the ls command you chose for the situation against the names from the selection and then add them to a new array if there is a match, like this:

string $all[] = `ls -l`;
string $sel[] = `ls -sl -l`;
string $ordered[];

for ($a in $all){
    for ($s in $sel){
        if ($s == $a){
            int $index = `size($ordered)`;
            stringArrayInsertAtIndex(($index + 1), $ordered, $s);
        }
    }
}
print($ordered);

 

I hope it helps!

0 Likes