Iterating Vertices

Hi All,

I am trying to iterating through a meshes vertices using script. If I already have the name of a "mesh" object in a string variable, can someone tell me how I get the number of vertices in the mesh?

Ultimately, I am iterating through the vertices in a skinCluster to get all the weights.

Thanks
Todd

QUOTE(tscott1213 @ 02/19/06, 07:06 AM) [snapback]228579[/snapback]
Ultimately, I am iterating through the vertices in a skinCluster to get all the weights.

Ultimately thats something you never want to do! See getAttr is a pretty heavy operation. Since the entire command actualy works with a database (mayas a database), just like no sane sql programmer would never do a loop to ask for each and every walue in text database you shouldnt do that in maya either, since each querry carries a quite hefty startingcost. You wantto do this ALL in as few querries as you and you can in 2! So get the entire dataset and then iterate the dataset.

Ok so ill need to teach you how maya realy works here, the thing is you should underatsnd taht the far MOST usefull section of yoru manual is the NODE REFERENCE, most pople dont seem to care but you should.

CODE
{
$clusters=ls ("-type", "skinCluster", listHistory);
for ($cluster in $clusters){
   $numVerts=getAttr -s ($cluster+".weightList");
   $bones=listConnections ($cluster+".matrix");
   $numBones= size($bones);
   $weights=getAttr ($cluster+".weightList[0:" +($numVerts-1)+"].w[0:"+($numBones-1)+"]");
      // note: be sure to subtract -1 or youll make
      // the arrays bigger all the time till maya crashes!
   print ($cluster+":\n");
   print $weights;
}
}

this prints out the rew data its ordered in vertex cluster order, for the selection. (you maya select multiple items if you wish its quite prettyprint)

so the first value is vertex 0 bone0 weight next is vertex 0 bone1 ... vertex 0 bone n then vertex 1 bone 0.... vertex n n.

Note doing only 2 gettar querries is about $numBones/2 times faster taht iterating each one separately now manipulating teh data afterwards in afor loop IS not a speed issue.

even prettyer print, contains abugfix (and i did fix it to the above):

CODE
{
$clusters=ls ("-type", "skinCluster", listHistory);
for ($cluster in $clusters){
   $numVerts=getAttr -s ($cluster+".weightList");
   $bones=listConnections ($cluster+".matrix");
   $numBones= size($bones);
   $weights=getAttr ($cluster+".weightList[0:" +($numVerts-1)+"].w[0:"+($numBones-1)+"]");

   print ($cluster+":\nBone:\t");
   for ($j=0;$j<$numBones;$j++)
       print ("\t"+$bones[$j]+"\t");
   print "\n";
   for ($i=0;$i<size($weights);$i+=$numBones){
     print ("vtx["+$i/2+"]:\t");
     for ($j=0;$j<$numBones;$j++)
       print ($weights[$i+$j]+"\t");
    print "\n";
   }
}
}

Thanks Joojaa...this is perfect.

I appreciate the lesson!

Hi,

A followup question that this has sparked...

You were able to get the entire list of weights for every vertex for every bone in one getAttr call. Is there a way to use setAttr to set everything in one call?

(I am having to rethink alot of my scripts after seeing how you did this.)

Thanks
Todd

yes in the same way excpet one peculiarity oof maya states that you need to use evel here since setAttr does not real array attribs but thather you must open it up (this used to work directly in realy old mayas but for some reason it does not work anymore). But even so one ecval can eb much faster than setting each and every one sparately.

Anyway this is by faar the most annyoing maya flaw.

Sorry to be slow here....would you mind showing me the statement that would set all the weights in one call using eval?

Also, I have "Complete Maya Programming" can you suggest any other good texts?

Thanks again.
Todd

edit:

Here is what I am trying, but is incorrect:

eval setAttr ($skinCluster+".weightList[0:"+($numVerts-1)+ "].w[0:"+($numBones-1)+"]") $weights;

Well this is info i HAVENT seen many other source except me talking about this extensively (its something ive experimented out theres no mention of this penalty andor startegy excpet hinted, ive learned it myself but im not the first to use it because ive seen scripts older than mine to use this). So i dont see much other choise than to get this info from me! As faras im concerned coders are morew interested ease of code! Tough wouldnt be hard to make a setArrayAttr command (hey new owners of maya READ THIS), since thsi would SPEED up a number of scripts by 1/10 and a number of them 1/100

Most bookls on mel read more like refernces

Yes its worng becaue you need to open wights aray into stthe command. Se you cant just pass a array, jut like i said you need to OPEN it as buch of floats (or because you use eval into a string)

this is easiest but slightly inefficientn (infact ist only winning on long arrays but wastes ALOT of mem!, so be sure to scope it right):

$cmd=("setAttr "+$skinCluster+".weightList[0:"+($numVerts-1)+"].w[0:"+($numBones-1)+"] ");
for ($item in $weights)
$cmd+=($item+" ");
eval $cmd;

a alternate way is to make it in few hadcoded lengths in a stairstep unction but ive never cared to time this. sicne i think its more important to make understandable code.

Ok, I didn't understand what you meant by OPEN until now.

Thanks again.

This type of a speed pickup is gold!

not to mention mak9ing coding and trasferall much more easy. Id like to see them expand most ndoes to accept arrays as equalient for opened arrays. Woulc nmake mel so much more noce to code.