- Main Page
- Classes
- Files
- Directories
- Examples

# ImportScene/DisplayMesh.cxx

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

       Copyright (C) 2012 Autodesk, Inc.
       All rights reserved.

       Use of this software is subject to the terms of the Autodesk license agreement
       provided at the time of installation or download, or which otherwise accompanies
       this software in either electronic or hard copy form.

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

    #include "DisplayMesh.h"

    #include "DisplayMaterial.h"
    #include "DisplayTexture.h"
    #include "DisplayLink.h"
    #include "DisplayShape.h"

    #define MAT_HEADER_LENGTH 200

    void DisplayControlsPoints(FbxMesh* pMesh);
    void DisplayPolygons(FbxMesh* pMesh);
    void DisplayMaterialMapping(FbxMesh* pMesh);
    void DisplayTextureMapping(FbxMesh* pMesh);
    void DisplayTextureNames( FbxProperty &pProperty, FbxString& pConnectionString );
    void DisplayMaterialConnections(FbxMesh* pMesh);
    void DisplayMaterialTextureConnections( FbxSurfaceMaterial* pMaterial,
                                           char * header, int pMatId, int l );

    void DisplayMesh(FbxNode* pNode)
    {
        FbxMesh* lMesh = (FbxMesh*) pNode->GetNodeAttribute ();

        DisplayString("Mesh Name: ", (char *) pNode->GetName());
        DisplayMetaDataConnections(lMesh);
        DisplayControlsPoints(lMesh);
        DisplayPolygons(lMesh);
        DisplayMaterialMapping(lMesh);
        DisplayMaterial(lMesh);
        DisplayTexture(lMesh);
        DisplayMaterialConnections(lMesh);
        DisplayLink(lMesh);
        DisplayShape(lMesh);
    }

    void DisplayControlsPoints(FbxMesh* pMesh)
    {
        int i, lControlPointsCount = pMesh->GetControlPointsCount();
        FbxVector4* lControlPoints = pMesh->GetControlPoints();

        DisplayString("    Control Points");

        for (i = 0; i < lControlPointsCount; i++)
        {
            DisplayInt("        Control Point ", i);
            Display3DVector("            Coordinates: ", lControlPoints[i]);

            for (int j = 0; j < pMesh->GetElementNormalCount(); j++)
            {
                FbxGeometryElementNormal* leNormals = pMesh->GetElementNormal( j);
                if (leNormals->GetMappingMode() == FbxGeometryElement::eByControlPoint)
                {
                    char header[100];
                    FBXSDK_sprintf(header, 100, "            Normal Vector: ");
                    if (leNormals->GetReferenceMode() == FbxGeometryElement::eDirect)
                        Display3DVector(header, leNormals->GetDirectArray().GetAt(i));
                }
            }
        }

        DisplayString("");
    }

    void DisplayPolygons(FbxMesh* pMesh)
    {
        int i, j, lPolygonCount = pMesh->GetPolygonCount();
        FbxVector4* lControlPoints = pMesh->GetControlPoints();
        char header[100];

        DisplayString("    Polygons");

        int vertexId = 0;
        for (i = 0; i < lPolygonCount; i++)
        {
            DisplayInt("        Polygon ", i);
            int l;

            for (l = 0; l < pMesh->GetElementPolygonGroupCount(); l++)
            {
                FbxGeometryElementPolygonGroup* lePolgrp = pMesh->GetElementPolygonGroup(l);
                switch (lePolgrp->GetMappingMode())
                {
                case FbxGeometryElement::eByPolygon:
                    if (lePolgrp->GetReferenceMode() == FbxGeometryElement::eIndex)
                    {
                        FBXSDK_sprintf(header, 100, "        Assigned to group: ");
                        int polyGroupId = lePolgrp->GetIndexArray().GetAt(i);
                        DisplayInt(header, polyGroupId);
                        break;
                    }
                default:
                    // any other mapping modes don't make sense
                    DisplayString("        \"unsupported group assignment\"");
                    break;
                }
            }

            int lPolygonSize = pMesh->GetPolygonSize(i);

            for (j = 0; j < lPolygonSize; j++)
            {
                int lControlPointIndex = pMesh->GetPolygonVertex(i, j);

                Display3DVector("            Coordinates: ", lControlPoints[lControlPointIndex]);

                for (l = 0; l < pMesh->GetElementVertexColorCount(); l++)
                {
                    FbxGeometryElementVertexColor* leVtxc = pMesh->GetElementVertexColor( l);
                    FBXSDK_sprintf(header, 100, "            Color vertex: ");

                    switch (leVtxc->GetMappingMode())
                    {
                    case FbxGeometryElement::eByControlPoint:
                        switch (leVtxc->GetReferenceMode())
                        {
                        case FbxGeometryElement::eDirect:
                            DisplayColor(header, leVtxc->GetDirectArray().GetAt(lControlPointIndex));
                            break;
                        case FbxGeometryElement::eIndexToDirect:
                            {
                                int id = leVtxc->GetIndexArray().GetAt(lControlPointIndex);
                                DisplayColor(header, leVtxc->GetDirectArray().GetAt(id));
                            }
                            break;
                        default:
                            break; // other reference modes not shown here!
                        }
                        break;

                    case FbxGeometryElement::eByPolygonVertex:
                        {
                            switch (leVtxc->GetReferenceMode())
                            {
                            case FbxGeometryElement::eDirect:
                                DisplayColor(header, leVtxc->GetDirectArray().GetAt(vertexId));
                                break;
                            case FbxGeometryElement::eIndexToDirect:
                                {
                                    int id = leVtxc->GetIndexArray().GetAt(vertexId);
                                    DisplayColor(header, leVtxc->GetDirectArray().GetAt(id));
                                }
                                break;
                            default:
                                break; // other reference modes not shown here!
                            }
                        }
                        break;

                    case FbxGeometryElement::eByPolygon: // doesn't make much sense for UVs
                    case FbxGeometryElement::eAllSame:   // doesn't make much sense for UVs
                    case FbxGeometryElement::eNone:       // doesn't make much sense for UVs
                        break;
                    }
                }
                for (l = 0; l < pMesh->GetElementUVCount(); ++l)
                {
                    FbxGeometryElementUV* leUV = pMesh->GetElementUV( l);
                    FBXSDK_sprintf(header, 100, "            Texture UV: ");

                    switch (leUV->GetMappingMode())
                    {
                    case FbxGeometryElement::eByControlPoint:
                        switch (leUV->GetReferenceMode())
                        {
                        case FbxGeometryElement::eDirect:
                            Display2DVector(header, leUV->GetDirectArray().GetAt(lControlPointIndex));
                            break;
                        case FbxGeometryElement::eIndexToDirect:
                            {
                                int id = leUV->GetIndexArray().GetAt(lControlPointIndex);
                                Display2DVector(header, leUV->GetDirectArray().GetAt(id));
                            }
                            break;
                        default:
                            break; // other reference modes not shown here!
                        }
                        break;

                    case FbxGeometryElement::eByPolygonVertex:
                        {
                            int lTextureUVIndex = pMesh->GetTextureUVIndex(i, j);
                            switch (leUV->GetReferenceMode())
                            {
                            case FbxGeometryElement::eDirect:
                            case FbxGeometryElement::eIndexToDirect:
                                {
                                    Display2DVector(header, leUV->GetDirectArray().GetAt(lTextureUVIndex));
                                }
                                break;
                            default:
                                break; // other reference modes not shown here!
                            }
                        }
                        break;

                    case FbxGeometryElement::eByPolygon: // doesn't make much sense for UVs
                    case FbxGeometryElement::eAllSame:   // doesn't make much sense for UVs
                    case FbxGeometryElement::eNone:       // doesn't make much sense for UVs
                        break;
                    }
                }
                for( l = 0; l < pMesh->GetElementNormalCount(); ++l)
                {
                    FbxGeometryElementNormal* leNormal = pMesh->GetElementNormal( l);
                    FBXSDK_sprintf(header, 100, "            Normal: ");

                    if(leNormal->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
                    {
                        switch (leNormal->GetReferenceMode())
                        {
                        case FbxGeometryElement::eDirect:
                            Display3DVector(header, leNormal->GetDirectArray().GetAt(vertexId));
                            break;
                        case FbxGeometryElement::eIndexToDirect:
                            {
                                int id = leNormal->GetIndexArray().GetAt(vertexId);
                                Display3DVector(header, leNormal->GetDirectArray().GetAt(id));
                            }
                            break;
                        default:
                            break; // other reference modes not shown here!
                        }
                    }

                }
                for( l = 0; l < pMesh->GetElementTangentCount(); ++l)
                {
                    FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent( l);
                    FBXSDK_sprintf(header, 100, "            Tangent: ");

                    if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
                    {
                        switch (leTangent->GetReferenceMode())
                        {
                        case FbxGeometryElement::eDirect:
                            Display3DVector(header, leTangent->GetDirectArray().GetAt(vertexId));
                            break;
                        case FbxGeometryElement::eIndexToDirect:
                            {
                                int id = leTangent->GetIndexArray().GetAt(vertexId);
                                Display3DVector(header, leTangent->GetDirectArray().GetAt(id));
                            }
                            break;
                        default:
                            break; // other reference modes not shown here!
                        }
                    }

                }
                for( l = 0; l < pMesh->GetElementBinormalCount(); ++l)
                {

                    FbxGeometryElementBinormal* leBinormal = pMesh->GetElementBinormal( l);

                    FBXSDK_sprintf(header, 100, "            Binormal: ");
                    if(leBinormal->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
                    {
                        switch (leBinormal->GetReferenceMode())
                        {
                        case FbxGeometryElement::eDirect:
                            Display3DVector(header, leBinormal->GetDirectArray().GetAt(vertexId));
                            break;
                        case FbxGeometryElement::eIndexToDirect:
                            {
                                int id = leBinormal->GetIndexArray().GetAt(vertexId);
                                Display3DVector(header, leBinormal->GetDirectArray().GetAt(id));
                            }
                            break;
                        default:
                            break; // other reference modes not shown here!
                        }
                    }
                }
                vertexId++;
            } // for polygonSize
        } // for polygonCount

        //check visibility for the edges of the mesh
        for(int l = 0; l < pMesh->GetElementVisibilityCount(); ++l)
        {
            FbxGeometryElementVisibility* leVisibility=pMesh->GetElementVisibility(l);
            FBXSDK_sprintf(header, 100, "    Edge Visibility : ");
            DisplayString(header);
            switch(leVisibility->GetMappingMode())
            {
                //should be eByEdge
            case FbxGeometryElement::eByEdge:
                //should be eDirect
                for(int j=0; j!=pMesh->GetMeshEdgeCount();++j)
                {
                    DisplayInt("        Edge ", j);
                    DisplayBool("              Edge visibility: ", leVisibility->GetDirectArray().GetAt(j));
                }

                break;
            }
        }
        DisplayString("");
    }

    void DisplayTextureNames( FbxProperty &pProperty, FbxString& pConnectionString )
    {
        int lLayeredTextureCount = pProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId);
        if(lLayeredTextureCount > 0)
        {
            for(int j=0; j<lLayeredTextureCount; ++j)
            {
                FbxLayeredTexture *lLayeredTexture = FbxCast <FbxLayeredTexture>(pProperty.GetSrcObject(FbxLayeredTexture::ClassId, j));
                int lNbTextures = lLayeredTexture->GetSrcObjectCount(FbxTexture::ClassId);
                pConnectionString += " Texture ";

                for(int k =0; k<lNbTextures; ++k)
                {
                    //lConnectionString += k;
                    pConnectionString += "\"";
                    pConnectionString += (char*)lLayeredTexture->GetName();
                    pConnectionString += "\"";
                    pConnectionString += " ";
                }
                pConnectionString += "of ";
                pConnectionString += pProperty.GetName();
                pConnectionString += " on layer ";
                pConnectionString += j;
            }
            pConnectionString += " |";
        }
        else
        {
            //no layered texture simply get on the property
            int lNbTextures = pProperty.GetSrcObjectCount(FbxTexture::ClassId);

            if(lNbTextures > 0)
            {
                pConnectionString += " Texture ";
                pConnectionString += " ";

                for(int j =0; j<lNbTextures; ++j)
                {
                    FbxTexture* lTexture = FbxCast <FbxTexture> (pProperty.GetSrcObject(FbxTexture::ClassId,j));
                    if(lTexture)
                    {
                        pConnectionString += "\"";
                        pConnectionString += (char*)lTexture->GetName();
                        pConnectionString += "\"";
                        pConnectionString += " ";
                    }
                }
                pConnectionString += "of ";
                pConnectionString += pProperty.GetName();
                pConnectionString += " |";
            }
        }
    }

    void DisplayMaterialTextureConnections( FbxSurfaceMaterial* pMaterial, char * header, int pMatId, int l )
    {
        if(!pMaterial)
            return;

        FbxString lConnectionString = "            Material %d -- ";
        //Show all the textures

        FbxProperty lProperty;
        //Diffuse Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse);
        DisplayTextureNames(lProperty, lConnectionString);

        //DiffuseFactor Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuseFactor);
        DisplayTextureNames(lProperty, lConnectionString);

        //Emissive Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sEmissive);
        DisplayTextureNames(lProperty, lConnectionString);

        //EmissiveFactor Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sEmissiveFactor);
        DisplayTextureNames(lProperty, lConnectionString);

        //Ambient Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sAmbient);
        DisplayTextureNames(lProperty, lConnectionString);

        //AmbientFactor Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sAmbientFactor);
        DisplayTextureNames(lProperty, lConnectionString);

        //Specular Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecular);
        DisplayTextureNames(lProperty, lConnectionString);

        //SpecularFactor Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecularFactor);
        DisplayTextureNames(lProperty, lConnectionString);

        //Shininess Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sShininess);
        DisplayTextureNames(lProperty, lConnectionString);

        //Bump Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sBump);
        DisplayTextureNames(lProperty, lConnectionString);

        //Normal Map Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap);
        DisplayTextureNames(lProperty, lConnectionString);

        //Transparent Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sTransparentColor);
        DisplayTextureNames(lProperty, lConnectionString);

        //TransparencyFactor Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
        DisplayTextureNames(lProperty, lConnectionString);

        //Reflection Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sReflection);
        DisplayTextureNames(lProperty, lConnectionString);

        //ReflectionFactor Textures
        lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sReflectionFactor);
        DisplayTextureNames(lProperty, lConnectionString);

        //Update header with material info
        bool lStringOverflow = (lConnectionString.GetLen() + 10 >= MAT_HEADER_LENGTH); // allow for string length and some padding for "%d"
        if (lStringOverflow)
        {
            // Truncate string!
            lConnectionString = lConnectionString.Left(MAT_HEADER_LENGTH - 10);
            lConnectionString = lConnectionString + "...";
        }
        FBXSDK_sprintf(header, 100, lConnectionString.Buffer(), pMatId, l);
        DisplayString(header);
    }

    void DisplayMaterialConnections(FbxMesh* pMesh)
    {
        int i, l, lPolygonCount = pMesh->GetPolygonCount();

        char header[MAT_HEADER_LENGTH];

        DisplayString("    Polygons Material Connections");

        //check whether the material maps with only one mesh
        bool lIsAllSame = true;
        for (l = 0; l < pMesh->GetElementMaterialCount(); l++)
        {

            FbxGeometryElementMaterial* lMaterialElement = pMesh->GetElementMaterial(l);
            if( lMaterialElement->GetMappingMode() == FbxGeometryElement::eByPolygon)
            {
                lIsAllSame = false;
                break;
            }
        }

        //For eAllSame mapping type, just out the material and texture mapping info once
        if(lIsAllSame)
        {
            for (l = 0; l < pMesh->GetElementMaterialCount(); l++)
            {

                FbxGeometryElementMaterial* lMaterialElement = pMesh->GetElementMaterial( l);
                if( lMaterialElement->GetMappingMode() == FbxGeometryElement::eAllSame)
                {
                    FbxSurfaceMaterial* lMaterial = pMesh->GetNode()->GetMaterial(lMaterialElement->GetIndexArray().GetAt(0));
                    int lMatId = lMaterialElement->GetIndexArray().GetAt(0);
                    if(lMatId >= 0)
                    {
                        DisplayInt("        All polygons share the same material in mesh ", l);
                        DisplayMaterialTextureConnections(lMaterial, header, lMatId, l);
                    }
                }
            }

            //no material
            if(l == 0)
                DisplayString("        no material applied");
        }

        //For eByPolygon mapping type, just out the material and texture mapping info once
        else
        {
            for (i = 0; i < lPolygonCount; i++)
            {
                DisplayInt("        Polygon ", i);

                for (l = 0; l < pMesh->GetElementMaterialCount(); l++)
                {

                    FbxGeometryElementMaterial* lMaterialElement = pMesh->GetElementMaterial( l);
                    FbxSurfaceMaterial* lMaterial = NULL;
                    int lMatId = -1;
                    lMaterial = pMesh->GetNode()->GetMaterial(lMaterialElement->GetIndexArray().GetAt(i));
                    lMatId = lMaterialElement->GetIndexArray().GetAt(i);

                    if(lMatId >= 0)
                    {
                        DisplayMaterialTextureConnections(lMaterial, header, lMatId, l);
                    }
                }
            }
        }
    }

    void DisplayMaterialMapping(FbxMesh* pMesh)
    {
        char* lMappingTypes[] = { "None", "By Control Point", "By Polygon Vertex", "By Polygon", "By Edge", "All Same" };
        char* lReferenceMode[] = { "Direct", "Index", "Index to Direct"};

        int lMtrlCount = 0;
        FbxNode* lNode = NULL;
        if(pMesh){
            lNode = pMesh->GetNode();
            if(lNode)
                lMtrlCount = lNode->GetMaterialCount();
        }

        for (int l = 0; l < pMesh->GetElementMaterialCount(); l++)
        {
            FbxGeometryElementMaterial* leMat = pMesh->GetElementMaterial( l);
            if (leMat)
            {
                char header[100];
                FBXSDK_sprintf(header, 100, "    Material Element %d: ", l);
                DisplayString(header);

                DisplayString("           Mapping: ", lMappingTypes[leMat->GetMappingMode()]);
                DisplayString("           ReferenceMode: ", lReferenceMode[leMat->GetReferenceMode()]);

                int lMaterialCount = 0;
                FbxString lString;

                if (leMat->GetReferenceMode() == FbxGeometryElement::eDirect ||
                    leMat->GetReferenceMode() == FbxGeometryElement::eIndexToDirect)
                {
                    lMaterialCount = lMtrlCount;
                }

                if (leMat->GetReferenceMode() == FbxGeometryElement::eIndex ||
                    leMat->GetReferenceMode() == FbxGeometryElement::eIndexToDirect)
                {
                    int i;

                    lString = "           Indices: ";

                    int lIndexArrayCount = leMat->GetIndexArray().GetCount();
                    for (i = 0; i < lIndexArrayCount; i++)
                    {
                        lString += leMat->GetIndexArray().GetAt(i);

                        if (i < lIndexArrayCount - 1)
                        {
                            lString += ", ";
                        }
                    }

                    lString += "\n";

                    printf(lString);
                }
            }
        }

        DisplayString("");
    }