Computer_icon
Feb 15, 2012
Post id: 309641 Report Item

I've created the following script to roughen the vertexes of selected shapes. I'd like this script to create history that could be animated - it would be like a 3D static if I could change the way the vertexes were roughened in time. Any ideas how that could be approached?

Thanks!

{

float $roughness = .1;
     
string  $allObjects[];
string  $obj;
    
int $vertexCount[];
    
float $x;
float $y;
float $z;
    
    $allObjects = `ls -selection`;
    
    // process each shape
    for ( $obj in $allObjects ) {
    
        // select next object
        select -r $obj;

        //    get the number of vertices used in the mesh
        $vertexCount = `polyEvaluate -v`;
            
        //    process each vertex
        for ( $i=0 ; $i < $vertexCount[0] ; $i++ )
            {
    
                // select next vertex                
                select -r ( $obj + ".vtx[" + $i + "]") ;
                $x = rand(-$roughness,$roughness);
                $y = rand(-$roughness,$roughness);
                $z = rand(-$roughness,$roughness);
                move -r $x $y $z ;
            }
    
        }
    
// re-select initial object selection
select -r $allObjects;

}

Dashboard_avatar
Feb 17, 2012
Post id: 309647 Report Item

Well yes, its easy actually.* Anyway, this is a perfect example of missunderstanding completely how one should approach mel or in fact any maya scriping tasks for that matter.
What you do is, you manually do the work. While instead you should arrange nodes to do tasks for you. Its a very different thing. Also dont select the verices pass a selection to move.
So what you do is you use a particle node as a softbody to do the change.
*unfortunately i dont sit in front of a computer capable of running maya so you need to either figure it out of my hint (it is sraightforward). Or wait till i get home and get the kids asleep

Dashboard_avatar
Feb 19, 2012
Post id: 309662 Report Item

Sorry someting came up.

Im simplifyiong a bit and assume WITH NO ERRORCHEKING that you select some vertices in only one node.












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


{
$highlight = `ls -hilite`;
$particle = `soft $highlight[0]`;
$temp=`ls -dag $particle`;
$pShape=$temp[1];
print $pShape;
addAttr -ln "roughness" -k 1 -dv 1 $highlight[0];
addAttr -ln "offset" -k 1 -dv 0 $highlight[0];
addAttr -ln "frequency" -k 1 -dv 5 $highlight[0];
addAttr -ln mag -dt doubleArray $pShape;
addAttr -ln mag0 -dt doubleArray $pShape;
$ctx = `currentCtx`;
makePaintable -attrType "doubleArray" -aa "mag" "particle" "mag0";
source "artAttrCreateMenuItems.mel";
artSetToolAndSelectAttr( "artAttrCtx", ("particle."+$pShape+".mag0") );
artAttrCtx -e -value 1 artAttrContext ;
artAttrCtx -e -clear artAttrContext;
$dyn = (".position = .position0 +"+
" .mag*"+$highlight[0]+".roughness*dnoise(.position0*"+
$highlight[0]+".frequency+"+$highlight[0]+".offset)");
print $dyn;
dynExpression -s $dyn
-c $pShape;
dynExpression -s $dyn
-rad $pShape;
setToolTo $ctx;
}
 




As you see its a bit more involved thinking



Computer_icon
Feb 21, 2012
Post id: 309666 Report Item

Thanks, it's helpful to see how different people approach the same problem. Unfortunately, this has the same effect as my original code. In order to get the randomness to animate, I put the code in an expression instead of a script. I'm going to try something along those lines.

Dashboard_avatar
Feb 21, 2012
Post id: 309667 Report Item

Stop, right there. It does animate, its just not animated which is a different thing.

The object now has 3 extra attributes roughness, offset and frequency. Animate any one of those and it animates the noise.

Computer_icon
Feb 24, 2012
Post id: 309683 Report Item

Oh, cool! That works great! I tried the following, which is probably a roundabout way of doing something similar:

{
float $Xpos;
float $Ypos;
float $Zpos;
int $vtxCount[];
float $randomness = .1;
string $refObject = "pCube1";
string $tarObject = "pCube2";

$vtxCount = `polyEvaluate -vertex $tarObject`;

            for($i=0;$i<$vtxCount[0];$i++)
            {

            // reads a point
            float $vtxPos[3] = `xform -q -ws -t ($refObject + ".vtx[" + $i + "]")`;
            print $vtxPos;
            
            // determines random XYZ
            $Xpos = ( $vtxPos[0] + rand(-$randomness,$randomness) );
            $Ypos = ( $vtxPos[1] + rand(-$randomness,$randomness) );
            $Zpos = ( $vtxPos[2] + rand(-$randomness,$randomness) );
            // moves a point                  
            xform -a -ws -t $Xpos $Ypos $Zpos ($tarObject + ".vtx[" + $i + "]");
            
            }
            
}

Dashboard_avatar
Feb 25, 2012
Post id: 309685 Report Item

There are several reasons why you want to avoid your version inside an expression:

1. It breaks undo!
2. Its slow
3. State is not stable, makes rendering frames again impossible*
4. Non referencable, the name is carved in stone; object does not duplicate well even with construction history copy
5. Its working against mayas evaluation graph so theres no trigger when values change -> unneccesery evaluations where not needed and missing eveluations where needeed.
6. Non graceful exit

Really the reason i do it in way that looks whacked form a coding perspective is that im teaching a node to do this and NOT program the act. If you wish to keep the same worldview you have now you should start developing nodes instead. In mel you have little choice.

There is clear evidence your doing something that's not node centric if you have a for loop that loops over components. Its fine if you intend to do it once however.

* noise was developed for this and few other reasons back in the 1980's by Ken Perlin, noise is the 3D artists version of rand for most things. And Ken later got a technical Oscar for hos work on noise in 1997, read more here.