What is wrong with this script?


#1

Hi

Please look at this part. I get an error with the substitute command

  //GET THE SELECTION
    string $wholeSel[] = `ls -sl`;
    
    //FILTER ONLY TARGET OBJECTS AND GET THEIR SHAPE NODES
    string $targetList[] = ls("-sl", "-hd", (size($wholeSel) - 1)); 
    
    //GET THE BASE OBJECT
    string $base = $wholeSel[size($wholeSel) - 1];
    
    //DUPLICATE THE BASE
   
    string $dupList[];
    string $baseCopy[];
    
    for ($i=0; $i<size($targetList); $i++)  
    {
       $dupList = `duplicate -rr -st $base`;
       $baseCopy[size($baseCopy)] = $dupList[0];
    }
   
    //RENAME THE BASE DUPLICATES TO THE TARGET NAMES
    string $newBaseCopy[];
    
     for ($d=0; $d<size($baseCopy); $d++)
    {
       rename($baseCopy[$d], (substitute("_L1", ($baseCopy[$d] = rename($baseCopy[$d], $targetList[$d])), "_R")));   <-ERROR HERE
    }

with this I only get my first object in the array renamed ONCE, but the second rename doesnt happen. “No object matches name”

Also sometimes I get substitute command eror saying to check arguments type. this happens only in this case. if I simplify the code with just variables instead of functions the erroe goes away and i get good result.

I also want to say that I am learning still.

Thank you


#2

I’m not a Mel expert, in fact I hate Mel.
You should learn Python instead :wink:

Sorry I’m not near a PC so I can’t give you any sample code or anything but I’ll tell you what I think you should look into.

I’m not really sure what are you trying to do with that code, you should have explain it.

From what I see you’re trying to duplicate objects with an _L suffix and rename them to _R. Some mirror tool perhaps?
But you are duplicating the same object, the last selects one, over and over with the same name in your first loop, so this new object will be automatically renamed to _L1, _L2, _L3, etc and then you’re trying to rename them all to the same name _R. That won’t work. You’re working around this replacing ‘_L1’ instead of _L but that will only work with the first duplicated object, the second one will be _L2 and the substitute command won’t find _L anywhere.

It could work if you use the substitute command with _L but then your result would be _R1,_R2,_R3 and all of them would be he same duplicated object.

Good luck


#3

Hey, thanks for the reply. Yes this is a mirroring tool for blendshapes
I have updated the script a bit
.I’ll copy and paste my post from another forum. This is only the for loop part:

So I have 6 objects. 3 of them are with “_L” as a suffix. And the other 3 have different unreleavent names. I want to rename these as the first 3 objects but switch the “_L” to “R”. I finally was able to do this. But it’s curios why I don’t get full result when using the commented out line. Basically I only get the first object renamed properly and get the second object just renamed without switching L to R. And nothing happens with the third. The error says “No object matches name” . If I run the for loop again. I get the second object renamed properly and the third renamed without the switch and so on. I suspect it has to do with variables.

$list is holding the spheres
$list_old is holding the other 3 objects

Thank you

    for ($x=0; $x<size($list); $x++)
        
        {
            $rename[$x] = (rename($list_old[$x], $list[$x]));
            $subs[$x] = (substitute("_L1", $rename[$x], "_R"));
            rename ($rename[$x], $subs[$x]);
        
            // rename ($rename[$x], ($subs[$x] = (substitute("_L1", ($rename[$x] = (rename($list_old[$x], $list[$x]))), "_R")))); -> this doesn't work
        }

I think this here also has the same problem you described. could you explain it a bit more?

Thank you


#4

I am incrementing the index. why would it duplicate the same object again?


#5

Well, to rename objects in the $list_old with $list, this code would be enough:

for ($x=0; $x<size($list); $x++){
            $subs = substitute("_L", $list[$x], "_R");
            rename ($list_old[$x], $subs);
}

That is considering $list_old and $list have the same length.
Keep it simple.

Or, if you want it in one line:

for ($x=0; $x<size($list); $x++){
            rename ($list_old[$x], substitute("_L", $list[$x], "_R"));
}

But I’m against these practices specially when you are learning.
Having the code in one line, or two lines won’t have any difference at all in speed or memory usage. Code optimization isn’t about making it shorter. It will only be difficult to read.

Anything with a bracket like $list[$x] means it is part of an array. If you don’t have or need an array, use strings. ($rename isn’t an array, doesn’t need to be one). This may work, but you are creating an array that you are not using. Just use a string variable and overwrite it in every iteration.

And with the commented line you are creating variables inside variables in the same sentence. I’d be surprised that would work. Don’t try to create variables or arrays inside variables or commands, or arguments. Meaning, don’t use $variable= inside a command or variable.

About duplicating the same object. In this code:

 for ($i=0; $i<size($targetList); $i++)  
    {
       $dupList = `duplicate -rr -st $base`;
       $baseCopy[size($baseCopy)] = $dupList[0];
    }

You have created an index variable $i that you are incrementing in every iteration.
BUT!! you are not using that index variable in your loop code, so you are doing the same thing n times.

Something like this:

$i =0;
duplicate $base
add the returned string to the array $baseCopy
increment $i

$i=1
duplicate $base
add the returned string to the array $baseCopy
increment $i

and keep doing the same thing while $i is less than size($targetList)

And seriously, consider Python if you want to increment your scripting skills.