Hello everyone,
I'm trying to learn MEL scripting coming from a background of Unity C#. Currently I'm working on a script that moves all selected vertices to 0 on the x-axis. I borrowed this script from another forum but it doesn't seem to work when the object has moved:
string $verts[] = `ls -sl -fl`;<br> for($vert in $verts)<br> {<br> select $vert;<br> float $vPos[] = `xform -q -t`;<br> move 0 $vPos[1] $vPos[2];<br> select -cl;<br> }<br>
Now, I'm trying to freeze the transformations and reset the pivot point to the origin so the above script does work. However,, in order to freeze the transformations I need to go back to object mode. But it seems that switching to object mode sometimes doesn't work. For example, when I create a new cube object, go into vertex selection mode, and select some vertices, I cannot go back to object mode with this line of code:
selectMode -object;
Why can't I switch to Object selection mode?
This is the full script I'm working on:
global proc MoveVerticesZeroX(){<br> <br> selectMode -object;<br> <br> xform -ws -pivots 0 0 0 ;<br> FreezeTransformations;<br> <br> selectMode -co;<br> selectType -alc 0 -v 1;<br> <br> string $verts[] = `ls -sl -fl`;<br> for($vert in $verts)<br> {<br> select $vert;<br> float $vPos[] = `xform -q -t`;<br> move 0 $vPos[1] $vPos[2];<br> select -cl;<br> }<br>}<br>
Replies
http://help.autodesk.com/cloudhelp/2017/CHS/Maya-Tech-Docs/Commands/move.html
In one line:
move -ws -x 0
Quick demo
https://www.dropbox.com/s/7xnp6er47na8l3p/2017-12-01_19-37-29.mp4?dl=0
Now I'm still wondering why the changing mode selection doesn't work...
If, however, you still want to know how to select move pivot to the origin and freeze transformation you really don't have to switch selection mode back and forward from Object to Component. The trick is that all you need is somehow to get the name of the object while you still have some components selected and without deselecting them (for example, some vertices selected).
The script goes like this:
// get object name when any componet is selected
string $getObjectName[] = `ls -hilite`;
// move pivot to Origin for "$getObjectName[0]" object
// freeze transformation for "$getObjectName[0]" object
This will have your components still selected while "in the background" doing positioning of pivot to the origin and freeze object transformations. This kind of thing is also very useful in lots of situation when you need to do something to your object and components and will reduce the code lines instead converting selection mode back and forward.
As for going from component to object mode, you can also use the same workflow as a workaround:
// get object name when any component is selected
string $getObjectName[] = `ls -hilite`;
// select the object
select -r $getObjectName[0];
Hope this helps.
Cheers.
Your workaround for toggling between the selection modes also seems to work well. Maybe it's me, but I'm still wondering why the
doesn't seem to work properly. Is this just a limitation/bug of the Mel scripting language or is something else going on?
If you use the -hilite flag with the ls command, you can potentially get more objects returned than just the object on which you have vertices selected.
For example, make two cylinders, select both objects, press F9, then select vertices on just one of the cylinders.
If you perform:
string $getObjectName[] = `ls -hilite`;
You get:
// Result: |pCylinder2 |pCylinder1 //
My suspicion is that you only want the transform returned upon which you have verts selected, not all "objects that are currently hilited for component selection." (Per the MEL command reference).
Also, whenever you perform an `ls` operation, it is strongly advisable to utilized the -long flag. This will return object long names. This protects you against identical object names that could be living in different groups.
For example:
If you have one of those cylinders selected and perform an `ls -sl`, you get a return of pCylinder1.
Now perform: select "pCylinder1"
You'll get:
// Error: line 1: More than one object matches name: pCylinder1 //
This can really screw you over when you start writing scripts for extremely large and potentially unkempt scenes. Better to be bulletproof from the start IMO.
Here is some code that will protect you from both issues:
string $shapeNodes[] = `ls -sl -objectsOnly -long`; //ObjectsOnly flag gives you the shape nodes from the selected components.
// Result: |group1|pCylinder1|pCylinderShape1 //
string $transformNode[] = `listTransforms $shapeNodes[0]`; //Gives you the transform node linked to the shape node.
// Result: group1|pCylinder1 //
Hope this is valuable to you, and my apologies if I stepped on anyone's toes in the process
The only change that could be done is to use "$getObjectName" instead of "$getObjectName[0]" so that not only the first object is affected but all in the array or which objects are highlighted...which may or may not be what you want too.
But yes, no worries. There are multiple ways of doing things with scripting so i never see things are right or wrong but it's more about what someone what to do exactly.