Polynormalpervertex

The goal of this script is to make a tool that will move all normals with individual offsets relative to their position. currently moving batch normals (with the maya tool) results in all normals facing the exact same direction. This is not good for spheres or pretty much anything else with a curve to it. The problem i have is when i put a slider for each axis and pass that variable into the "polyNormalPerVertex" for the axis it only registers on the 0 or 180 degrees. here is the script:

window -h 50 -w 50 -s true -t normalEdit;
columnLayout;

string $xSlider = floatSliderGrp -dc "xSet(floatSliderGrp -q -v $xSlider)" //slider that sends its float to proc xSet
-cc "xSet(
floatSliderGrp -q -v $xSlider)"
-min -1.0 -max 1.0 -f true -l X -pre 4
;

string $ySlider = floatSliderGrp -dc "ySet(floatSliderGrp -q -v $ySlider)" //slider that sends its float to proc ySet
-cc "ySet(
floatSliderGrp -q -v $ySlider)"
-min -1.0 -max 1.0 -f true -l Y -pre 4
;

string $zSlider = floatSliderGrp -dc "zSet(floatSliderGrp -q -v $zSlider)" //slider that sends its float to proc zSet
-cc "zSet(
floatSliderGrp -q -v $zSlider)"
-min -1.0 -max 1.0 -f true -l Z -pre 4
;

showWindow;

proc xSet(float $xOffSet){
//string $verts[] = filterExpand -selectionMask 31; //store object's verts in an array
//$numVerts = size $verts; //sore how many verts in array
polyNormalPerVertex -rel -x $xOffSet; //todo loop through verts and adjust them individually
print $xOffSet;
};
proc ySet(float $yOffSet){
//string $verts[] = filterExpand -selectionMask 31;
//$numVerts = size $verts;
polyNormalPerVertex -rel -y $yOffSet;
print $yOffSet;
};
proc zSet(float $zOffSet){
//string $verts[] = filterExpand -selectionMask 31;
//$numVerts = size $verts;
polyNormalPerVertex -rel -z $zOffSet;
print $zOffSet;
};

hmm.. before I assemble a script to do that with -relative, I'd checked if if works manually ;]
And I see: Doesn't seem so!

eg: polyNormalPerVertex -rel -y 0.1; just turns all normals up. As if the "-rel"-flag has no meaning at all.

But I'd love to have such a script as well!!! But I doubt the slider-version is handy enough for my high requisitions !!

I thought about clustering al concerned vertices, but clusters don't change normals.
Seems the only reliable thing would be to query the normal values and reasign a fresh calculated ones per vertex (or even per vertex face)

well you cant actually do enything usefull with this in animation. since the normals get recalculated on each deform so...

Good for statics. (but especialy usefull is the ability to push one faces normals out to meet the next faces normal!)

Hi Joojaa!
What u mean? the clusters?

Do you have a cool idea how one could turn vertexnormals relatively?

And don't tell me via APi ;]

no it doen't work manually. that's the point of making the script. eventually i will have to query each vertex for its position do some math based on that vector to move it accordingly. but the main problem i'm worried about at the moment is why the sliders variable doesn't move the normal correctly. try the script as it sits. the normal jumps from 1 to -1 with no intermediate. also it overides the other two degrees of freedom even though the -x -y -z flags are set.

Nah! If it doesn't work manually, why do you expect it to work in a script? :]

I managed to make it work with a given offset like
[b]rotateMyVertexNormals 10 0 0;

[/b]but I gotta go now. I show you later.

it works fine on individual vertex normals manually, not batch.

really? Not here! Doesn't on one neither on many.
Can you show me how?

btw: here is my attempt:

I just take the vector, rotate it, apply it! Simple as that:

CODE
global proc ezNormalTool_relRotNormals(float $rx, float $ry, float $rz)
{
    // get vertices flattened with ls -fl
    string $sel[] = ls -sl;
    string $vtxs[] = ls("-fl",polyListComponentConversion -tv);
    select -d;
    for ($vtx in $vtxs)
    {
        // if the vertex' normals are splitted handle each vertexFace for itself
        if (ez\_IsNormalSplitted $vtx)
        {
            string $vtxFs[] = ls("-fl",polyListComponentConversion("-toVertexFace", $vtx));
            for ($vtxF in $vtxFs)
            {
                float $normal[] = polyNormalPerVertex -q -xyz $vtxF;
                float $newNormal[] = ezRotateVector($normal[0], $normal[1], $normal[2], $rx, $ry, $rz);
                polyNormalPerVertex -xyz $newNormal[0] $newNormal[1] $newNormal[2] $vtxF;
            }
        }
        // else do the whole vertex
        else
        {
            float $normal[3] = polyNormalPerVertex -q -xyz $vtx;
            float $newNormal[] = ezRotateVector($normal[0], $normal[1], $normal[2], $rx, $ry, $rz);
            polyNormalPerVertex -xyz $newNormal[0] $newNormal[1] $newNormal[2] $vtx;
        }
    }
    select $sel;
}

// you gonna need these as well:

global proc int ez_IsNormalSplitted(string $vertex)
{
     // get all vertexFaces from this vertex
     string $vtxFs[] = ls("-fl",polyListComponentConversion("-toVertexFace",$vertex));
     int $numVFs = size($vtxFs);

     // loop them all but the last
     for($i1 = 0; $i1 < ($numVFs - 1); $i1++)
     {
         for($i2 = ($i1 + 1); $i2 < $numVFs; $i2++)
         {
             vector $vVtxF1 = `polyNormalPerVertex -q -xyz $vtxFs[$i1]`;
             vector $vVtxF2 = `polyNormalPerVertex -q -xyz $vtxFs[$i2]`;
             // if their vectors match
             if ($vVtxF1 != $vVtxF2)
                 return 1;
         }
     }
     return 0;
}

global proc float[] ez_RotateVector(float $vx, float $vy, float $vz, float $rx, float $ry, float $rz)
{
    float $temp, $sx, $cx, $sy, $cy, $sz, $cz;

    $rx = deg_to_rad($rx);
    $ry = deg_to_rad($ry);
    $rz = deg_to_rad($rz);

    $sx = sin($rx);
    $cx = cos($rx);
    $sy = sin($ry);
    $cy = cos($ry);
    $sz = sin($rz);
    $cz = cos($rz);

    $temp = $vy * $cx - $vz * $sx;
    $vz   = $vy * $sx + $vz * $cx;
    $vy   = $temp;

    $temp = $vz * $sy + $vx * $cy;
    $vz   = $vz * $cy - $vx * $sy;
    $vx   = $temp;

    $temp = $vx * $cz - $vy * $sz;
    $vy   = $vx * $sz + $vy * $cz;
    $vx   = $temp;

    float $resV[] = {$vx, $vy, $vz};
    normalize($resV);
    return $resV;
}

now ezNormalTool_relRotNormals 10 0 0; rotates all your vertices normals in the selection by 10 degrees on x-axis.

The problem with the slider is also: A slider is a absolute control its hard to make it do relative changes. You'd need to compare the last and the current value to make a valid change. And so you,d need to store your value somehow. maybe in the ui as well not in global vars.

QUOTE(ewerybody @ 07/02/07, 12:48 AM) [snapback]269032[/snapback]
The problem with the slider is also: A slider is a absolute control its hard to make it do relative changes. You'd need to compare the last and the current value to make a valid change. And so you,d need to store your value somehow. maybe in the ui as well not in global vars.

Just make a copy of your mesh and refer to that, it's the perfect backup of the normals.

or write it to blind data?

QUOTE
Just make a copy of your mesh and refer to that, it's the perfect backup of the normals.

what?!? at every drag as I slide? for a simple float value?

But backing up the mesh is a valuable option! As polyNormalPervertex crashes your Normals sometimes. Do you have similar experiences?