UVSample/main.cxx

/**************************************************************************************

 Copyright (C) 2010 Autodesk, Inc. and/or its licensors.
 All Rights Reserved.

 The coded instructions, statements, computer programs, and/or related material 
 (collectively the "Data") in these files contain unpublished information 
 proprietary to Autodesk, Inc. and/or its licensors, which is protected by 
 Canada and United States of America federal copyright law and by international 
 treaties. 
 
 The Data may not be disclosed or distributed to third parties, in whole or in
 part, without the prior written consent of Autodesk, Inc. ("Autodesk").

 THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
 ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO
 WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING
 BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, 
 NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR USE. 
 WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT THE OPERATION
 OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE. 
 
 IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS
 OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES
 OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE DAMAGES OR OTHER
 SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE
 OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND),
 HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF LIABILITY, WHETHER DERIVED
 FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE), OR OTHERWISE,
 ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE,
 WHETHER OR NOT AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS
 OR DAMAGE. 

**************************************************************************************/

//
// This example shows to the user how to get UV information from mesh,
// and how to modify UV information on a specific UV set.
// Steps:
//  1. Initialize FBX SDK Manager and FBX Scene
//  2. Load the input file to scene
//  3. Access Node and its mesh
//  4. Get the UVs Information from the mesh
//  5. Modify the UV information and apply to the mesh
//  6. Save the scene to output file
//  7. Destroy the FBX SDK Manager and FBX Scene

//FBX SDK headers
#include <fbxsdk.h>
#include "../Common/Common.h"
#include <fbxfilesdk/fbxfilesdk_nsuse.h>


//input file path
static const char* sInputFile = "Sadface.FBX";

//output file path
static const char* sOutputFile = "Happyface.FBX";


//We load the all the UV information from the mesh
void LoadUVInformation(KFbxMesh* pMesh);

//We modify certain UV set and save the UV to mesh
void SaveUVInformation(KFbxMesh* pMesh);


int main()
{

    //FBX SDK Default Manager
    KFbxSdkManager* lSdkManager = NULL;

    //Scene to load from file
    KFbxScene* lScene = NULL;

    // Prepare the FBX SDK.
    InitializeSdkObjects(lSdkManager, lScene);

    // Load the scene.
    bool lResult = LoadScene(lSdkManager, lScene, sInputFile);

    if(lResult == false)
    {
        printf("\n\nAn error occurred while loading the scene...");
    }
    else 
    {
        //Get the first node in the scene
        KFbxNode* lNodeOfInterest = lScene->GetRootNode()->GetChild(0);
        if(lNodeOfInterest)
        {
            KFbxMesh* lMeshOFInterest = lNodeOfInterest->GetMesh();
            if(lMeshOFInterest)
            {
                //first, load the UV information and display them
                LoadUVInformation(lMeshOFInterest);

                //then, modify certain uv set and save it
                SaveUVInformation(lMeshOFInterest);

                //save the modified scene to file
                SaveScene(lSdkManager, lScene, sOutputFile);
            }
        }
    }

    // Destroy all objects created by the FBX SDK.
    DestroySdkObjects(lSdkManager);
    return 0;
}

void LoadUVInformation(KFbxMesh* pMesh)
{
    //get all UV set names
    KStringList lUVSetNameList;
    pMesh->GetUVSetNames(lUVSetNameList);

    //iterating over all uv sets
    for (int lUVSetIndex = 0; lUVSetIndex < lUVSetNameList.GetCount(); lUVSetIndex++)
    {
        //get lUVSetIndex-th uv set
        const char* lUVSetName = lUVSetNameList.GetStringAt(lUVSetIndex);
        const KFbxGeometryElementUV* lUVElement = pMesh->GetElementUV(lUVSetName);

        if(!lUVElement)
            continue;

        // only support mapping mode eBY_POLYGON_VERTEX and eBY_CONTROL_POINT
        if( lUVElement->GetMappingMode() != KFbxGeometryElement::eBY_POLYGON_VERTEX &&
            lUVElement->GetMappingMode() != KFbxGeometryElement::eBY_CONTROL_POINT )
            return;

        //direct array, where holds the actual uv data
        const int lDataCount = lUVElement->GetDirectArray().GetCount();

        //index array, where holds the index referenced to the uv data
        const bool lUseIndex = lUVElement->GetReferenceMode() != KFbxGeometryElement::eDIRECT;
        const int lIndexCount= (lUseIndex) ? lUVElement->GetIndexArray().GetCount() : 0;

        //iterating through the data by polygon
        const int lPolyCount = pMesh->GetPolygonCount();

        if( lUVElement->GetMappingMode() == KFbxGeometryElement::eBY_CONTROL_POINT )
        {
            for( int lPolyIndex = 0; lPolyIndex < lPolyCount; ++lPolyIndex )
            {
                // build the max index array that we need to pass into MakePoly
                const int lPolySize = pMesh->GetPolygonSize(lPolyIndex);
                for( int lVertIndex = 0; lVertIndex < lPolySize; ++lVertIndex )
                {
                    KFbxVector2 lUVValue;

                    //get the index of the current vertex in control points array
                    int lPolyVertIndex = pMesh->GetPolygonVertex(lPolyIndex,lVertIndex);

                    //the UV index depends on the reference mode
                    int lUVIndex = lUseIndex ? lUVElement->GetIndexArray().GetAt(lPolyVertIndex) : lPolyVertIndex;

                    lUVValue = lUVElement->GetDirectArray().GetAt(lUVIndex);

                    //User TODO:
                    //Print out the value of UV(lUVValue) or log it to a file
                }
            }
        }
        else if (lUVElement->GetMappingMode() == KFbxGeometryElement::eBY_POLYGON_VERTEX)
        {
            int lPolyIndexCounter = 0;
            for( int lPolyIndex = 0; lPolyIndex < lPolyCount; ++lPolyIndex )
            {
                // build the max index array that we need to pass into MakePoly
                const int lPolySize = pMesh->GetPolygonSize(lPolyIndex);
                for( int lVertIndex = 0; lVertIndex < lPolySize; ++lVertIndex )
                {
                    if (lPolyIndexCounter < lIndexCount)
                    {
                        KFbxVector2 lUVValue;

                        //the UV index depends on the reference mode
                        int lUVIndex = lUseIndex ? lUVElement->GetIndexArray().GetAt(lPolyIndexCounter) : lPolyIndexCounter;

                        lUVValue = lUVElement->GetDirectArray().GetAt(lUVIndex);

                        //User TODO:
                        //Print out the value of UV(lUVValue) or log it to a file

                        lPolyIndexCounter++;
                    }
                }
            }
        }
    }
}

void SaveUVInformation(KFbxMesh* pMesh)
{
    //iterating over all uv sets
    for (int lUVSetIndex = 0; lUVSetIndex < pMesh->GetElementUVCount(); lUVSetIndex++)
    {
        //get lUVSetIndex-th uv set
        const KFbxGeometryElementUV* lUVElement = pMesh->GetElementUV(lUVSetIndex);

        if(!lUVElement)
            continue;

        // only support mapping mode eBY_POLYGON_VERTEX and eBY_CONTROL_POINT
        if( lUVElement->GetMappingMode() != KFbxGeometryElement::eBY_POLYGON_VERTEX &&
            lUVElement->GetMappingMode() != KFbxGeometryElement::eBY_CONTROL_POINT )
            return;

        //new UV data
        int lNewUVCount = 274/2;
        double lNewUVData[274] = 
        {
            0.000499486923217773,0.000499725341796875,0.10039958357811,0.000499695539474487,0.200299650430679,0.0004996657371521,0.300199747085571,0.0004996657371521,0.400099813938141,0.000499635934829712,0.49999988079071,0.000499606132507324,0.59989994764328,0.000499576330184937,0.69980001449585,0.000499546527862549,0.799700140953064,0.000499546527862549,0.899600148200989,0.000499516725540161,0.999500274658203,0.000499486923217773,0.000499516725540161,0.100399821996689,0.100399613380432,0.100399792194366,0.200299680233002,0.100399762392044,0.300199747085571,0.100399762392044,0.400099813938141,0.100399732589722,0.499999910593033,0.100399702787399,0.599900007247925,0.100399672985077,0.699800074100494,0.100399643182755,0.799700140953064,0.100399643182755,0.899600207805634,0.100399613380432,0.999500274658203,0.10039958357811,0.000499546527862549,0.200299888849258,0.100399643182755,0.200299859046936,0.200299710035324,0.400099903345108,0.300199776887894,0.400099903345108,0.400099843740463,0.40009993314743,0.499999940395355,0.400099962949753,0.599900007247925,0.400099992752075,0.699800074100494,0.400100022554398,0.799700140953064,0.400100022554398,0.899600267410278,0.200299680233002,0.999500334262848,0.200299650430679,0.000499546527862549,0.30019998550415,0.100399643182755,0.300199925899506,0.200299710035324,0.300199806690216,0.300199806690216,0.300199836492538,0.400099873542786,0.300199866294861,0.499999940395355,0.300199866294861,0.599900007247925,0.300199925899506,0.699800133705139,0.300199925899506,0.799700140953064,0.300199955701828,0.899600267410278,0.300199747085571,0.999500334262848,0.300199747085571,0.000499576330184937,0.40010005235672,0.100399672985077,0.400100022554398,0.200299739837646,0.200299739837646,0.300199806690216,0.200299769639969,0.400099903345108,0.200299799442291,0.499999970197678,0.200299799442291,0.59990006685257,0.200299829244614,0.699800133705139,0.200299859046936,0.799700200557709,0.200299888849258,0.899600267410278,0.400099813938141,0.999500393867493,0.400099813938141,0.000499606132507324,
            0.50000011920929,0.100399702787399,0.50000011920929,0.200299769639969,0.500000059604645,0.300199866294861,0.500000059604645,0.40009993314743,0.5,0.5,0.5,0.59990006685257,0.499999970197678,0.699800133705139,0.499999940395355,0.799700260162354,0.499999940395355,0.899600267410278,0.499999910593033,0.999500393867493,0.49999988079071,0.000499635934829712,0.599900186061859,0.100399732589722,0.599900186061859,0.200299799442291,0.599900126457214,0.300199866294861,0.599900126457214,0.40009993314743,0.599900126457214,0.5,0.59990006685257,0.599900126457214,0.59990006685257,0.699800193309784,0.599900007247925,0.799700260162354,0.599900007247925,0.899600327014923,0.599900007247925,0.999500393867493,0.59989994764328,0.0004996657371521,0.699800252914429,0.100399762392044,0.699800252914429,0.200299829244614,0.699800252914429,0.300199896097183,0.699800193309784,0.400099962949753,0.699800193309784,0.500000059604645,0.699800133705139,0.599900126457214,0.699800133705139,0.699800193309784,0.699800133705139,0.799700260162354,0.699800074100494,0.899600386619568,0.699800074100494,0.999500453472137,0.69980001449585,0.0004996657371521,0.799700379371643,0.100399762392044,0.799700319766998,0.200299829244614,0.799700260162354,0.300199925899506,0.799700260162354,0.400099992752075,0.799700260162354,0.500000059604645,0.799700260162354,0.599900126457214,0.799700200557709,0.699800252914429,0.799700140953064,0.799700260162354,0.799700140953064,0.899600386619568,0.799700140953064,0.999500453472137,0.799700140953064,0.000499695539474487,0.899600386619568,0.100399792194366,0.899600386619568,0.200299859046936,0.899600386619568,0.300199925899506,0.899600386619568,0.400100022554398,0.899600327014923,0.50000011920929,0.899600267410278,0.599900186061859,0.899600267410278,0.699800252914429,0.899600267410278,0.799700319766998,0.899600267410278,0.899600386619568,0.899600207805634,0.999500513076782,0.899600148200989,0.000499725341796875,0.999500513076782,0.100399821996689,0.999500513076782,0.200299888849258,0.999500453472137,0.30019998550415,0.999500453472137,
            0.40010005235672,0.999500393867493,0.50000011920929,0.999500393867493,0.599900186061859,0.999500393867493,0.699800252914429,0.999500334262848,0.799700379371643,0.999500334262848,0.899600386619568,0.999500274658203,0.999500513076782,0.999500274658203,0.200299710035324,0.200299829244614,0.300199776887894,0.200299829244614,0.400099843740463,0.200299799442291,0.499999940395355,0.200299769639969,0.599900007247925,0.200299739837646,0.699800074100494,0.200299710035324,0.799700140953064,0.200299710035324,0.200299710035324,0.300199925899506,0.799700140953064,0.300199776887894,0.200299739837646,0.400099992752075,0.300199806690216,0.400099962949753,0.400099903345108,0.40009993314743,0.499999970197678,0.40009993314743,0.59990006685257,0.400099903345108,0.699800133705139,0.400099873542786,0.799700200557709,0.400099843740463
        };

        //new UV index data
        int lNewUVIndexCount = 600;
        int lNewUVIndices[600] = 
        {
            11,0,12,1,12,0,12,1,13,2,13,1,13,2,14,3,14,2,14,3,15,4,15,3,15,4,16,5,16,4,16,5,17,6,17,5,17,6,18,7,18,6,18,7,19,8,19,7,19,8,20,9,20,8,20,9,21,10,21,9,22,11,23,12,23,11,23,12,121,13,121,12,121,13,122,14,122,13,122,14,123,15,123,14,123,15,124,16,124,15,124,16,125,17,125,16,125,17,126,18,126,17,126,18,127,19,127,18,127,19,31,20,31,19,31,20,32,21,32,20,33,22,34,23,34,22,34,23,128,121,128,23,35,24,36,25,36,24,36,25,37,26,37,25,37,26,38,27,38,26,38,27,39,28,39,27,39,28,40,29,40,28,40,29,41,30,41,29,129,127,42,31,42,127,42,31,43,32,43,31,44,33,45,34,45,33,45,34,130,128,130,34,46,35,47,36,47,35,47,36,48,37,48,36,48,37,49,38,49,37,49,38,50,39,50,38,50,39,51,40,51,39,51,40,52,41,52,40,136,129,53,42,53,129,53,42,54,43,54,42,55,44,56,45,56,44,56,45,57,130,57,45,57,130,58,131,58,130,58,131,59,132,59,131,59,132,60,133,60,132,60,133,61,134,61,133,61,134,62,135,62,134,62,135,63,136,63,135,63,136,64,53,64,136,64,53,65,54,65,53,66,55,67,56,67,55,67,56,68,57,68,56,68,57,69,58,69,57,69,58,70,59,70,58,70,59,71,60,71,59,71,60,72,61,72,60,72,61,73,62,73,61,73,62,74,63,74,62,74,63,75,64,75,63,75,64,76,65,76,64,77,66,78,67,78,66,78,67,79,68,79,67,79,68,80,69,80,68,80,69,81,70,81,69,81,70,82,71,82,70,82,71,83,72,83,71,83,72,84,73,84,72,84,73,85,74,85,73,85,74,86,75,86,74,86,75,87,76,87,75,88,77,89,78,89,77,89,78,90,79,90,78,90,79,91,80,91,79,91,80,92,81,92,80,92,81,93,82,93,81,93,82,94,83,94,82,94,83,95,84,95,83,95,84,96,85,96,84,96,85,97,86,97,85,97,86,98,87,98,86,99,88,100,89,100,88,100,89,101,90,101,89,101,90,102,91,102,90,102,91,103,92,103,91,103,92,104,93,104,92,104,93,105,94,105,93,105,94,106,95,106,94,106,95,107,96,107,95,107,96,108,97,108,96,108,97,109,98,109,97,110,99,111,100,111,99,111,100,112,101,112,100,112,101,113,102,113,101,113,102,114,103,114,102,114,103,115,104,115,103,115,104,116,105,116,104,116,105,117,106,117,105,117,106,118,107,118,106,118,107,119,108,119,107,119,108,120,109,120,108
        };

        //set new UV data to direct array
        lUVElement->GetDirectArray().Resize(lNewUVCount);
        for(int lUVIndex = 0; lUVIndex < lNewUVCount; lUVIndex++)
        {
            KFbxVector2 lUV(lNewUVData[2*lUVIndex], lNewUVData[2*lUVIndex+1]);
            lUVElement->GetDirectArray().SetAt(lUVIndex, lUV);
        }

        //set new UV index data to index array
        lUVElement->GetIndexArray().Resize(lNewUVIndexCount);
        for(int lUVIndex = 0; lUVIndex < lNewUVIndexCount; lUVIndex++)
        {
            lUVElement->GetIndexArray().SetAt(lUVIndex, lNewUVIndices[lUVIndex]);
        }

        return;
    }
}