#include "DisplayMesh.h"
#include "DisplayMaterial.h"
#include "DisplayTexture.h"
#include "DisplayLink.h"
#include "DisplayShape.h"
#if defined (FBXSDK_ENV_MAC)
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
#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:
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;
}
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;
}
}
break;
case FbxGeometryElement::eByPolygon:
case FbxGeometryElement::eAllSame:
case FbxGeometryElement::eNone:
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;
}
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;
}
}
break;
case FbxGeometryElement::eByPolygon:
case FbxGeometryElement::eAllSame:
case FbxGeometryElement::eNone:
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;
}
}
}
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;
}
}
}
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;
}
}
}
vertexId++;
}
}
for(int l = 0; l < pMesh->GetElementVisibilityCount(); ++l)
{
FbxGeometryElementVisibility* leVisibility=pMesh->GetElementVisibility(l);
FBXSDK_sprintf(header, 100, " Edge Visibility : ");
DisplayString(header);
switch(leVisibility->GetMappingMode())
{
case FbxGeometryElement::eByEdge:
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>();
if(lLayeredTextureCount > 0)
{
for(int j=0; j<lLayeredTextureCount; ++j)
{
FbxLayeredTexture *lLayeredTexture = pProperty.GetSrcObject<FbxLayeredTexture>(j);
int lNbTextures = lLayeredTexture->GetSrcObjectCount<FbxTexture>();
pConnectionString += " Texture ";
for(int k =0; k<lNbTextures; ++k)
{
pConnectionString += "\"";
pConnectionString += (char*)lLayeredTexture->GetName();
pConnectionString += "\"";
pConnectionString += " ";
}
pConnectionString += "of ";
pConnectionString += pProperty.GetName();
pConnectionString += " on layer ";
pConnectionString += j;
}
pConnectionString += " |";
}
else
{
int lNbTextures = pProperty.GetSrcObjectCount<FbxTexture>();
if(lNbTextures > 0)
{
pConnectionString += " Texture ";
pConnectionString += " ";
for(int j =0; j<lNbTextures; ++j)
{
FbxTexture* lTexture = pProperty.GetSrcObject<FbxTexture>(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 -- ";
FbxProperty lProperty;
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sDiffuseFactor);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sEmissive);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sEmissiveFactor);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sAmbient);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sAmbientFactor);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecular);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sSpecularFactor);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sShininess);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sBump);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sTransparentColor);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sReflection);
DisplayTextureNames(lProperty, lConnectionString);
lProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sReflectionFactor);
DisplayTextureNames(lProperty, lConnectionString);
bool lStringOverflow = (lConnectionString.GetLen() + 10 >= MAT_HEADER_LENGTH);
if (lStringOverflow)
{
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");
bool lIsAllSame = true;
for (l = 0; l < pMesh->GetElementMaterialCount(); l++)
{
FbxGeometryElementMaterial* lMaterialElement = pMesh->GetElementMaterial(l);
if( lMaterialElement->GetMappingMode() == FbxGeometryElement::eByPolygon)
{
lIsAllSame = false;
break;
}
}
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);
}
}
}
if(l == 0)
DisplayString(" no material applied");
}
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)
{
const char* lMappingTypes[] = { "None", "By Control Point", "By Polygon Vertex", "By Polygon", "By Edge", "All Same" };
const 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";
FBXSDK_printf(lString);
}
}
}
DisplayString("");
}