Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Vertex Normal Rotation Alignment Tool v1.0

Vertex Normal Rotation Alignment Tool v1.0

YetiTech
Advocate Advocate
343 Views
0 Replies
Message 1 of 1

Vertex Normal Rotation Alignment Tool v1.0

YetiTech
Advocate
Advocate

Vertex Normal Rotation Alignment Tool v1.0 [Maya Script]


This script will set the vertex normal rotations to the same value as the vertex normal rotations of another object (2 separate skeleton meshes) if the vertex are in the same position space. All the vertex of the 2nd object that matched will be selected to show which vertex was aligned.

Select 2 objects first being the object you want the vertex normal rotations to change and execute the script.

Extremely useful if you have multiple skeleton mesh heads that all share a single skeleton mesh body where you want to set all the (overlapping head & body vertex) head normal vertex rotations to match the same value as the body vertex normal rotation while retaining the vertex normal rotations of the body. 


YetiTech_0-1725103852213.png

YetiTech_1-1725103871753.jpeg

 

 

 

////////////////////////////////////////////////////////////////////////////
//  /$$     /$$          /$$     /$$ /$$$$$$$$                  /$$       //    
// |  $$   /$$/         | $$    |__/|__  $$__/                 | $$       //    
//  \  $$ /$$//$$$$$$  /$$$$$$   /$$   | $$  /$$$$$$   /$$$$$$$| $$$$$$$  //    
//   \  $$$$//$$__  $$|_  $$_/  | $$   | $$ /$$__  $$ /$$_____/| $$__  $$ //    
//    \  $$/| $$$$$$$$  | $$    | $$   | $$| $$$$$$$$| $$      | $$  \ $$ //    
//     | $$ | $$_____/  | $$ /$$| $$   | $$| $$_____/| $$      | $$  | $$ //    
//     | $$ |  $$$$$$$  |  $$$$/| $$   | $$|  $$$$$$$|  $$$$$$$| $$  | $$ //    
//     |__/  \_______/   \___/  |__/   |__/ \_______/ \_______/|__/  |__/ //    
//                                                                        //                                                                                                                                                      
//      /$$$$$$   /$$                     /$$ /$$                         //        
//     /$$__  $$ | $$                    | $$|__/                         //        
//    | $$  \__//$$$$$$   /$$   /$$  /$$$$$$$ /$$  /$$$$$$   /$$$$$$$     //        
//    |  $$$$$$|_  $$_/  | $$  | $$ /$$__  $$| $$ /$$__  $$ /$$_____/     //        
//     \____  $$ | $$    | $$  | $$| $$  | $$| $$| $$  \ $$|  $$$$$$      //        
//     /$$  \ $$ | $$ /$$| $$  | $$| $$  | $$| $$| $$  | $$ \____  $$     //        
//    |  $$$$$$/ |  $$$$/|  $$$$$$/|  $$$$$$$| $$|  $$$$$$/ /$$$$$$$/     //        
//     \______/   \___/   \______/  \_______/|__/ \______/ |_______/      //            
////////////////////////////////////////////////////////////////////////////  
//YetiTech $tudios                                                        //
//Vertex Normal Rotation Alignment Tool v1.0 2024                         //
//by Nikhil Jeewa (◣_◢)                                                  //
////////////////////////////////////////////////////////////////////////////

//Use case: Matches the vertex of 2 objects that are overlapping. Sets the vertex normal rotation of first object to the same vertex normal rotation value of the 2nd object and selects all the matched vertex of the 2nd object to show what got matched.

//Instructions: 1. Select 2 objects, the first object being the object you want the vertex normal rotations to change. 2. Execute script.

//Note: Can be use used for any 2 objects that has matching vertex. Useful for character that has multiple heads and share same 1 body, retains the body vertex normal rotations and only changes the head normal vertex rotation to match the body (head being first selected object).  

string $objSel[] = `ls -sl`;
if (size($objSel) == 2) {
    // Get the selected Objs
    string $headObj = $objSel[0]; // Assuming the first selected Obj is the head
    string $bodyObj = $objSel[1]; // Assuming the second selected Obj is the body
    select -cl;

    // Vertex indices for head and body
    int $vertexCountH[] = `polyEvaluate -vertex $objSel[0]`;
    int $vertexCountB[] = `polyEvaluate -vertex $objSel[1]`;
    int $headV = $vertexCountH[0];
    int $bodyV = $vertexCountB[0]; 

    // Create empty array for selecting matched body vertex
    int $matchedB[] = {};
    
    // Query all vertex positions at once
    vector $headPositions[] = `xform -q -ws -t ($headObj + ".vtx[*]")`;
    vector $bodyPositions[] = `xform -q -ws -t ($bodyObj + ".vtx[*]")`;

    // Loop through all head vertices and get their translations
    int $successCount = 0;
    float $tolerance = 0.001; // Adjust tolerance as needed

    print("Starting vertex matching...\n");

    for ($i = 0; $i < $headV; $i++) {
        vector $headPos = $headPositions[$i];

        // Loop through all body vertices and compare their translations
        for ($j = 0; $j < $bodyV; $j++) {
            vector $bodyPos = $bodyPositions[$j];

            // If the translations match (within tolerance)
            if (abs($headPos.x - $bodyPos.x) < $tolerance &&
                abs($headPos.y - $bodyPos.y) < $tolerance &&
                abs($headPos.z - $bodyPos.z) < $tolerance) {
                $successCount++;
            
                // Set the vertex normal rotation of the head to the same value as the body vertex normal rotation  
                float $normals[] = `polyNormalPerVertex -q -xyz ($bodyObj + ".vtx[" + $j + "]")`;
                polyNormalPerVertex -xyz $normals[0] $normals[1] $normals[2] ($headObj + ".vtx[" + $i + "]");        

                // Matched body vertex for selection
                $matchedB[size($matchedB)] = $j;

                print("Matched head vertex " + $i + " with body vertex " + $j + "\n");

                break; // No need to check other body vertices for this head vertex
            }
        }
    }
    // Select Matched Body Vertex
    for ($i = 0; $i < size($matchedB); $i++) {
        select -add ($bodyObj + ".vtx[" + $matchedB[$i] + "]");
    }
    // Print the number of successful matches
    print ("Number of successful vertex matches: " + $successCount + "\n");
} else {
    print("Select 2 objects!\n");
}

 

 

 

FBX LIMITATIONS: IF ANYBODY AT AUTODESK WORKING ON FBX CAN FIX THIS PLEASE!

What I discovered is that if a mesh is having only skin cluster or if a mesh is having only blend shapes, after using script>export(separately)>reimport the vertex normal rotations of 2 skeleton meshes where vertex is overlapping are still aligned in the exact position script works flawless however if a mesh is having both skin cluster and blend shapes after using script>export(separately)>reimport the vertex normal rotations get slightly off set this is likely due to the combination of both skin cluster and blend shapes being influenced by the tangent space.

Experiment:
Create sphere>duplicate>lock normals> delete half of the one sphere and the other half of the other sphere>experiment>Export>Reimport


EDIT: I found a work around! 🍻


 NIKHIL JEEWA -CEO/Founder & Technical Director @ YetiTech $tudios (◣_◢) | Retargeting Script [MEL]
0 Likes
344 Views
0 Replies
Replies (0)