import_fbx.h
Go to the documentation of this file.
00001 #ifndef IMPORT_FBX
00002 #define IMPORT_FBX
00003 
00004 #include<vcg/complex/allocate.h>
00005 #include <wrap/callback.h>
00006 #include <wrap/io_trimesh/io_mask.h>
00007 #include <wrap/io_trimesh/io_material.h>
00008 #include <vcg/space/color4.h>
00009 #include <fbxsdk.h>
00010 #include <vcg/complex/algorithms/update/bounding.h>
00011 #include <fstream>
00012 #include <string>
00013 #include <vector>
00014 #include <cmath>
00015 #include <map>
00016 
00017 
00018 /******************************
00019 ImporterFBX is the class devoted to import the info contained in a FBX file inside a mesh defined following the vcg standards.
00020 In order to compile the following class you need to:
00021         - download the VCGlib from our SVN server and put the code in ../../vcglib
00022         - download from Autodesk website the FBXSDK-2012.1 and put the lib and include folders in ../fbx-2012.1
00023 */
00024 
00025 template <class OpenMeshType>
00026 class ImporterFBX
00027 {
00028 public:
00029 
00030         class Info
00031         {
00032         public:
00033 
00034                 Info()
00035                 {
00036                         mask    = 0;
00037                         cb              = 0;
00038                         numVertices = 0;
00039                         numFaces = 0;
00040                         numMeshPatches = 0;
00041                 }
00042 
00044                 int mask;  
00045 
00047                 // it returns the current position, and formats a string with a description of what th efunction is doing (loading vertexes, faces...)
00048                 vcg::CallBackPos *cb;
00049 
00051                 int numVertices;
00054                 int numFaces;
00056                 int numMeshPatches;
00057 
00058         }; // end class
00059         
00060         typedef typename OpenMeshType::VertexPointer VertexPointer;
00061         typedef typename OpenMeshType::ScalarType ScalarType;
00062         typedef typename OpenMeshType::VertexType VertexType;
00063         typedef typename OpenMeshType::FaceType FaceType;
00064         typedef typename OpenMeshType::VertexIterator VertexIterator;
00065         typedef typename OpenMeshType::FaceIterator FaceIterator;
00066         typedef typename OpenMeshType::CoordType CoordType;
00067         typedef typename OpenMeshType::VertexType::ColorType ColorType;
00068         typedef typename OpenMeshType::VertexType::ColorType::ScalarType CSType;
00069 private:
00070         class VCGMaterialBridge
00071         {
00072         private:
00073                 //colorAttributeName is something like: diffuse color,ambient color etc.
00074                 void insertMaterialInfoAndTextureName(KFbxSurfaceMaterial& mat,const char* colorAttributeName,OpenMeshType& m)
00075                 {
00076                         MaterialInfo matinfo;   
00077                         matinfo.setSurfaceMaterial(&mat);
00078                         //bool hastextcoords = (vcg::tri::HasPerWedgeTexCoord(m) || vcg::tri::HasPerVertexTexCoord(m));
00079                         //bool hascolors =  (vcg::tri::HasPerWedgeColor(m) || vcg::tri::HasPerVertexColor(m) || vcg::tri::HasPerFaceColor(m));
00080                         KFbxFileTexture* tex = matinfo.getTextureFileObject(colorAttributeName); 
00081                         if(tex)
00082                         {
00083                                 const char* texfile = tex->GetFileName();
00084                                 std::vector<std::string>::iterator it = std::find(m.textures.begin(),m.textures.end(),texfile);
00085                                 if (it == m.textures.end())
00086                                 {
00087                                         m.textures.push_back(texfile);
00088                                         matinfo.setTextureIndex(m.textures.size() - 1);
00089                                 }
00090                                 else
00091                                 {
00092                                         int dist = int(std::distance(m.textures.begin(),it));
00093                                         matinfo.setTextureIndex(dist);
00094                                 }
00095                         }       
00096                         else
00097                         {
00098                                 if (mat.GetClassId().Is(KFbxSurfaceLambert::ClassId))
00099                                 {
00100                                         KFbxPropertyDouble3 diffProp = ((KFbxSurfaceLambert* ) (&mat))->Diffuse;
00101                                         fbxDouble3 diffCol      = diffProp.Get();
00102                                         vcg::Color4b tmpc = vcg::Color4b(diffCol[0] * 255,diffCol[1] * 255,diffCol[2] * 255,255);
00103                                         matinfo.setColor(tmpc);
00104                                 }
00105                         }
00106                         material[colorAttributeName] = matinfo;
00107                 }
00108         public:
00109                 //given a texture or color attribute return
00110 
00111                 VCGMaterialBridge(OpenMeshType& m,KFbxSurfaceMaterial& mat)
00112                         :material()
00113                 {
00114                         insertMaterialInfoAndTextureName(mat,KFbxSurfaceMaterial::sDiffuse,m);
00115                 }
00116 
00117                 class MaterialInfo
00118                 {
00119                 private:
00120                         int textindex;
00121                         ColorType color;
00122                         bool hascolor;
00123                         KFbxSurfaceMaterial* surfMat;
00124                 public:
00125                         MaterialInfo():hascolor(false),textindex(-1),surfMat(NULL){}
00126                         void setColor(const ColorType& col) {color = col;hascolor= true;}
00127                         void setTextureIndex(const int i) {textindex = i;}
00128                         bool hasColor() const {return hascolor;}
00129                         bool hasTexture() const {return (textindex != -1);}
00130                         int getTextureIndex() const {return textindex;}
00131                         KFbxSurfaceMaterial* getSurfaceMaterial() const {return surfMat;}
00132                         void setSurfaceMaterial(KFbxSurfaceMaterial* mat) {surfMat = mat;}
00133                         KFbxFileTexture* getTextureFileObject (const char* attributeName) 
00134                         {
00135                                 if (surfMat)
00136                                 {       
00137                                         KFbxProperty prop = surfMat->FindProperty(attributeName);
00138                                         if(prop.IsValid())      
00139                                         {
00140                                                 int texnum = prop.GetSrcObjectCount(KFbxTexture::ClassId);
00141                                                 //the texnum value should be or 0 or 1 (i.e. for a diffuse texture i should have at most one texture file) but in order to avoid extremely strange file... 
00142                                                 if (texnum > 0)
00143                                                         return KFbxCast <KFbxFileTexture> (prop.GetSrcObject(KFbxTexture::ClassId,0));
00144                                                 else
00145                                                         return NULL;
00146                                         }
00147                                 }
00148                                 return NULL;
00149                         }
00150 
00151                         ColorType getColor() const {return color;}
00152                 };
00153 
00154                 MaterialInfo* getMaterial(const char* attr)
00155                 {
00156                         typename std::map<const char*,MaterialInfo>::iterator it = material.find(attr);
00157                         if (it != material.end())
00158                                 return &(it->second);
00159                         return NULL;
00160                 }
00161 
00162         private:
00163                 std::map<const char*,MaterialInfo> material;
00164         };
00165         
00166         static int ImportNode(OpenMeshType& m,KFbxNode* node,KFbxPose* pose,KFbxXMatrix* globPosMat,Info &oi)
00167         {
00168                 int result = E_NOERROR;
00169                 if (node)
00170                 {
00171                         KFbxXMatrix mat = getGlobalMatrix(node, KTime(), pose, globPosMat);
00172 
00173 
00174                         KFbxNodeAttribute* attr = node->GetNodeAttribute();
00175                         if (attr != NULL)
00176                         {
00177                                 KFbxNodeAttribute::EAttributeType att = attr->GetAttributeType();
00178                                 if (attr->GetAttributeType() == KFbxNodeAttribute::eMESH)
00179                                 {
00180                                         KFbxXMatrix geoOff = GetGeometry(node);
00181                                         KFbxXMatrix final = mat * geoOff;
00182 
00183                                         result = ImportMesh(m,node,final,oi);
00184                                 }
00185 
00186                         }
00187                         for(int ii = 0;ii < node->GetChildCount();++ii)
00188                                 ImportNode(m,node->GetChild(ii),pose,&mat,oi);                                  
00189                 }
00190                 return result;
00191         }
00192 
00193         static int ImportScene(OpenMeshType& m,KFbxScene* scene,Info &oi)
00194         {
00195                 scene->ConnectTextures();
00196                 KFbxPose* pose = NULL;
00197                 int ii = scene->GetPoseCount(); 
00198                 if (ii > 0)
00199                         pose = scene->GetPose(ii-1);
00200                 //KFbxAnimEvaluator* eval = scene->GetEvaluator();
00201                 KFbxNode* node = scene->GetRootNode();
00202                 int result = E_NOERROR;
00203                 KFbxXMatrix globPosMat;
00204                 for (int ii = 0; ii < scene->GetRootNode()->GetChildCount(); ++ii)
00205                         result = ImportNode(m,scene->GetRootNode()->GetChild(ii),pose,&globPosMat,oi);
00206                 return result;
00207         }
00208 
00209         static int ImportMesh(OpenMeshType& m,KFbxNode* node,const KFbxXMatrix& mat,Info& oi)
00210         {
00211                 KFbxMesh* newMesh = node->GetMesh();
00212                 if (!newMesh->IsTriangleMesh())
00213                 {
00214                         KFbxGeometryConverter* conv = new KFbxGeometryConverter(newMesh->GetFbxSdkManager());
00215                         newMesh = conv->TriangulateMesh(newMesh);
00216                 }
00217                 //KFbxMatrix mat2(mat);
00218                 vcg::Matrix44<ScalarType> mat2;
00219                 for(int ll = 0;ll < 4;++ll)
00220                         for(int vv = 0;vv < 4;++vv)
00221                                 mat2[ll][vv] = mat[vv][ll];
00222 
00223                 
00224                 vcg::Matrix33<ScalarType> matnorm;
00225                 for(int ll = 0;ll < 3;++ll)
00226                         for(int vv = 0;vv < 3;++vv)
00227                                 matnorm[ll][vv] = mat[vv][ll];
00228 
00229                 int matnum = node->GetSrcObjectCount(KFbxSurfaceMaterial::ClassId);
00230                 KFbxLayerElementArrayTemplate< int >* matarr = NULL;
00231                 bool found = newMesh->GetMaterialIndices(&matarr);
00232                 //displacement of material inside m.textures and number of textures inside the material
00233                 std::vector<VCGMaterialBridge> matAtlas; 
00234                 for (int matind = 0; matind < matnum; ++matind)
00235                 {
00236                         KFbxSurfaceMaterial *mater =  KFbxCast <KFbxSurfaceMaterial>(node->GetSrcObject(KFbxSurfaceMaterial::ClassId, matind));
00237                         matAtlas.push_back(VCGMaterialBridge(m,*mater));
00238                 }
00239                 size_t vertDispl = m.vert.size();
00240                 int currmeshvert = newMesh->GetControlPointsCount();
00241                 vcg::tri::Allocator<OpenMeshType>::AddVertices(m,currmeshvert);
00242                 int currmeshface = newMesh->GetPolygonCount();
00243                 size_t faceDispl = m.face.size();
00244                 vcg::tri::Allocator<OpenMeshType>::AddFaces(m,currmeshface);
00245                 KFbxVector4* posVert = newMesh->GetControlPoints();
00246                 KFbxLayerElementArrayTemplate<KFbxVector2>* UVArr = NULL;   
00247                 int uvparcount = newMesh->GetElementUVCount();
00248 
00249                 KFbxLayer* lnorm = newMesh->GetLayer(0,KFbxLayerElement::eNORMAL);
00250                 KFbxLayerElementNormal* normalLayer = NULL;
00251                 if (lnorm)
00252                         normalLayer =  lnorm->GetNormals();
00253                 KFbxLayerElement::EMappingMode normalMapMode = KFbxLayerElement::eNONE;
00254                 if (normalLayer)
00255                         normalMapMode = normalLayer->GetMappingMode();
00256                 KFbxLayer* lcol = newMesh->GetLayer(0,KFbxLayerElement::eVERTEX_COLOR);
00257                 KFbxLayerElementVertexColor* colorLayer = NULL;
00258                 if (lcol)
00259                         colorLayer =  lcol->GetVertexColors();
00260                 KFbxLayerElement::EMappingMode colorMapMode = KFbxLayerElement::eNONE;
00261                 if (colorLayer)
00262                         colorMapMode = colorLayer->GetMappingMode();
00263 
00264                 newMesh->GetTextureUV(&UVArr, KFbxLayerElement::eDIFFUSE_TEXTURES); 
00265 
00266                 int numFacPlusVert = oi.numFaces + oi.numVertices;
00267                 float det = mat2.Determinant();
00268                 bool invert = (det< 0.0);
00269                 for(int ii = 0;ii < currmeshvert;++ii)
00270                 {
00271 
00272                         ScalarType a = ScalarType(posVert[ii][0]);
00273                         ScalarType b = ScalarType(posVert[ii][1]);
00274                         ScalarType c = ScalarType(posVert[ii][2]);
00275                         vcg::Point4<ScalarType> fbxpos(a,b,c,ScalarType(1.0));
00276                         fbxpos = mat2 * fbxpos;
00277                         CoordType t(fbxpos[0],fbxpos[1],fbxpos[2]); 
00278                         m.vert[ii + vertDispl].P() = t;
00279                         /*if (vcg::tri::HasPerVertexColor(m) && )*/
00280                         if (vcg::tri::HasPerVertexNormal(m) && (normalLayer) && (normalMapMode ==  KFbxLayerElement::eBY_CONTROL_POINT))
00281                         {
00282                                 KFbxVector4 n;
00283                                 int normInd = -1;
00284                                 switch(normalLayer->GetReferenceMode())
00285                                 {
00286                                 case (KFbxLayerElement::eDIRECT):
00287                                         {
00288                                                 normInd = ii;
00289                                                 break;
00290                                         }
00291                                 case (KFbxLayerElement::eINDEX_TO_DIRECT):
00292                                         {
00293                                                 normInd = normalLayer->GetIndexArray()[ii];
00294                                                 break;
00295                                         }
00296                                 }
00297                                 n = normalLayer->GetDirectArray()[normInd]; 
00298                                 CoordType nn(n[0],n[1],n[2]);
00299                                 nn = (matnorm * nn);
00300 
00301                                 nn.Normalize();
00302                                 //if (invert)
00303                                 //      nn = -nn;
00304                                 m.vert[ii + vertDispl].N() = nn;
00305                         }
00306                         if (vcg::tri::HasPerVertexColor(m) && (colorLayer) && (colorMapMode ==  KFbxLayerElement::eBY_CONTROL_POINT))
00307                         {
00308                                 KFbxColor c;
00309                                 int colorInd = -1;
00310                                 switch(colorLayer->GetReferenceMode())
00311                                 {
00312                                 case (KFbxLayerElement::eDIRECT):
00313                                         {
00314                                                 colorInd = ii;
00315                                                 break;
00316                                         }
00317                                 case (KFbxLayerElement::eINDEX_TO_DIRECT):
00318                                         {
00319                                                 colorInd = colorLayer->GetIndexArray()[ii];
00320                                                 break;
00321                                         }
00322                                 }
00323                                 c = colorLayer->GetDirectArray()[colorInd];
00324                                 vcg::Color4b vcgcol(c[0] * 255,c[1] * 255,c[2] * 255,c[3] * 255);
00325                                 m.vert[ii + vertDispl].C() = vcgcol;
00326                         }
00327                 }
00328 
00329                 int* index = newMesh->GetPolygonVertices();
00330                 bool allsame = false;
00331                 int matarrsize = -1;
00332                 if (matarr)
00333                         matarrsize = matarr->GetCount();
00334                 if (matarrsize == 1)
00335                         allsame = true;
00336 
00337                 for(int ii = 0;ii < currmeshface;++ii)
00338                 {
00339                         int diffusematind = -1;
00340                         int matptr = -1;
00341                         typename VCGMaterialBridge::MaterialInfo* mymat = NULL;
00342                         if (matAtlas.size() > 0)
00343                         {
00344                                 if ((!allsame) && (matarrsize == currmeshface))
00345                                         matptr = (*matarr)[ii];
00346                                 else
00347                                 {
00348                                         if (allsame) 
00349                                         {
00350                                                 matptr = (*matarr)[0];  
00351                                         }
00352                                 }
00353                                 if ((matptr >= 0) && (matptr < matAtlas.size()))
00354                                 {
00355                                         mymat = matAtlas[matptr].getMaterial(KFbxSurfaceMaterial::sDiffuse);
00356                                         if (mymat && mymat->hasTexture())
00357                                                 diffusematind = mymat->getTextureIndex();
00358                                 }
00359                                 else
00360                                         if (matptr == node->GetMaterialCount())
00361                                         {
00362                                                 mymat = matAtlas[matptr-1].getMaterial(KFbxSurfaceMaterial::sDiffuse);
00363                                                 if (mymat && mymat->hasTexture())
00364                                                         diffusematind = mymat->getTextureIndex();
00365                                         }
00366                         }
00367                         for (int jj = 0;jj < 3;++jj)
00368                         {
00369                                 VertexIterator mov = m.vert.begin();
00370                                 std::advance(mov,index[ii * 3 + jj] + vertDispl);
00371                                 int invind = (3 - jj) % 3;
00372                                 if (!invert)
00373                                         m.face[ii + faceDispl].V(jj) = &(*mov);
00374                                 else
00375                                         m.face[ii + faceDispl].V(invind) = &(*mov);
00376                                 if (vcg::tri::HasPerWedgeTexCoord(m) && (uvparcount > 0) && mymat && mymat->hasTexture())
00377                                 {
00378                                         int texind = -1;
00379                                         KFbxLayerElement::EReferenceMode mapmode = newMesh->GetElementUV(0)->GetReferenceMode();
00380                                         if (mapmode == KFbxLayerElement::eINDEX_TO_DIRECT)
00381                                                 texind  = newMesh->GetTextureUVIndex(ii,jj);
00382                                         else 
00383                                                 if (mapmode == KFbxLayerElement::eDIRECT)
00384                                                         texind = ii * 3 + jj;
00385                                         if (UVArr)
00386                                         {
00387                                                 
00388                                                 KFbxVector2 texcoord =  UVArr->GetAt(texind); 
00389                                                 if (!invert)
00390                                                 {
00391                                                         m.face[ii + faceDispl].WT(jj).U() = ScalarType(texcoord[0]);
00392                                                         m.face[ii + faceDispl].WT(jj).V() = ScalarType(texcoord[1]);
00393                                                         m.face[ii + faceDispl].WT(jj).N() = diffusematind;
00394                                                 }
00395                                                 else
00396                                                 {
00397                                                         m.face[ii + faceDispl].WT(invind).U() = ScalarType(texcoord[0]);
00398                                                         m.face[ii + faceDispl].WT(invind).V() = ScalarType(texcoord[1]);
00399                                                         m.face[ii + faceDispl].WT(invind).N() = diffusematind;
00400                                                 }
00401                                         }
00402                                 }
00403 
00404                                 else 
00405                                         if (vcg::tri::HasPerVertexColor(m) && mymat && mymat->hasColor())
00406                                         {
00407                                                 if (!invert)
00408                                                         m.face[ii + faceDispl].V(jj)->C() = mymat->getColor();
00409                                                 else
00410                                                         m.face[ii + faceDispl].V(invind)->C() = mymat->getColor();
00411                                         }
00412                         }
00413                         if (oi.cb)
00414                         {
00415                                 char numstr[33];
00416                                 sprintf(numstr,"%d",oi.numMeshPatches);
00417                                 std::string st("Loading Vertices and Faces from ");
00418                                 st = st + numstr + " submeshes";
00419                                 oi.cb( (100*(m.vert.size() +m.face.size()))/ numFacPlusVert, st.c_str());
00420                         }
00421                 }
00422                 
00423                 //std::string tx = m.textures[firstTexInd];
00424                 return E_NOERROR;
00425         }       
00426 
00427         static void LoadMaskNode(KFbxNode* node, Info &oi)
00428         {
00429                 if (node)
00430                 {
00431                         KFbxNodeAttribute* attr = node->GetNodeAttribute();
00432                         if (attr != NULL)
00433                         {
00434                                 KFbxNodeAttribute::EAttributeType att = attr->GetAttributeType();
00435                                 if (attr->GetAttributeType() == KFbxNodeAttribute::eMESH)
00436                                 {
00437                                         int matnum = node->GetSrcObjectCount(KFbxSurfaceMaterial::ClassId);
00438                                         KFbxMesh* newMesh = node->GetMesh();
00439                                         int uvparcount = newMesh->GetElementUVCount();
00440                                         if (uvparcount > 0)
00441                                                 oi.mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
00442 
00443                                         KFbxLayer* lcolo = newMesh->GetLayer(0,KFbxLayerElement::eVERTEX_COLOR);
00444                                         if (matnum || lcolo)
00445                                                 oi.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
00446                                         KFbxLayer* lnorm = newMesh->GetLayer(0,KFbxLayerElement::eNORMAL);
00447                                         KFbxLayerElementNormal* nnom = lnorm->GetNormals();
00448                                         if (lnorm)      
00449                                                 oi.mask |= vcg::tri::io::Mask::IOM_VERTNORMAL;
00450                                         oi.numVertices = oi.numVertices + newMesh->GetControlPointsCount();
00451                                         if (!newMesh->IsTriangleMesh())
00452                                         {
00453                                                 KFbxGeometryConverter* conv = new KFbxGeometryConverter(newMesh->GetFbxSdkManager());
00454                                                 newMesh = conv->TriangulateMesh(newMesh);
00455                                         }
00456                                         oi.numFaces = oi.numFaces + newMesh->GetPolygonCount();
00457                                         oi.numMeshPatches += 1;
00458                                 }
00459                         }
00460                         for(int ii = 0;ii < node->GetChildCount();++ii)
00461                                 LoadMaskNode(node->GetChild(ii),oi);                                    
00462                 }
00463         }
00464 
00465         static KFbxXMatrix getGlobalMatrix(KFbxNode* pNode, const KTime& pTime, KFbxPose* pPose, KFbxXMatrix* pParentGlobalPosition = NULL)
00466         {
00467                 KFbxXMatrix lGlobalPosition;
00468                 bool        lPositionFound = false;
00469 
00470                 if (pPose)
00471                 {
00472                         int lNodeIndex = pPose->Find(pNode);
00473 
00474                         if (lNodeIndex > -1)
00475                         {
00476                                 if (pPose->IsBindPose() || !pPose->IsLocalMatrix(lNodeIndex))
00477                                 {
00478                                         lGlobalPosition = GetPoseMatrix(pPose, lNodeIndex);
00479                                 }
00480                                 else
00481                                 {
00482                                         KFbxXMatrix lParentGlobalPosition;
00483 
00484                                         if (pParentGlobalPosition)
00485                                         {
00486                                                 lParentGlobalPosition = *pParentGlobalPosition;
00487                                         }
00488                                         else
00489                                         {
00490                                                 if (pNode->GetParent())
00491                                                 {
00492                                                         lParentGlobalPosition = getGlobalMatrix(pNode->GetParent(), pTime, pPose);
00493                                                 }
00494                                         }
00495 
00496                                         KFbxXMatrix lLocalPosition = GetPoseMatrix(pPose, lNodeIndex);
00497                                         lGlobalPosition = lParentGlobalPosition * lLocalPosition;
00498                                 }
00499 
00500                                 lPositionFound = true;
00501                         }
00502                 }
00503 
00504                 if (!lPositionFound)
00505                 {
00506                         lGlobalPosition = pNode->EvaluateGlobalTransform(pTime);
00507                 }
00508 
00509                 return lGlobalPosition;
00510         }
00511 
00512         static KFbxXMatrix GetPoseMatrix(KFbxPose* pPose, int pNodeIndex)
00513         {
00514                 KFbxXMatrix lPoseMatrix;
00515                 KFbxMatrix lMatrix = pPose->GetMatrix(pNodeIndex);
00516 
00517                 memcpy((double*)lPoseMatrix, (double*)lMatrix, sizeof(lMatrix.mData));
00518 
00519                 return lPoseMatrix;
00520         }
00521 
00522         static KFbxXMatrix GetGeometry(KFbxNode* pNode)
00523         {
00524                 const KFbxVector4 lT = pNode->GetGeometricTranslation(KFbxNode::eSOURCE_SET);
00525                 const KFbxVector4 lR = pNode->GetGeometricRotation(KFbxNode::eSOURCE_SET);
00526                 const KFbxVector4 lS = pNode->GetGeometricScaling(KFbxNode::eSOURCE_SET);
00527 
00528                 return KFbxXMatrix(lT, lR, lS);
00529         }
00530 
00531 public:
00532         /*****
00533                 Enum containing possible error codes you can get opening an FBX file.
00534         */
00535         enum FBXError 
00536         {
00537                 // Successfull opening
00538                 E_NOERROR = 0,                                                                                                  
00539 
00540                 // Critical Opening Errors (only even numbers)
00541                 E_CANTCREATEFBXMANAGER  = 1,    
00542                 E_CANTCREATEFBXSCENE    = 2,
00543                 E_CANTCREATEFBXIMPORTER = 3,            
00544                 E_CANTFINDFILE                  = 4,    
00545                 E_CANTFINDFBXFILE               = 5,
00546                 E_CANTIMPORTFBXFILE             = 6     
00547         };
00548 
00549         /****
00550                 Function devoted to check if a given error is critical or the elaboration can go on.
00551         */
00552         static bool ErrorCritical(int err)
00553         { 
00554                 if(err == E_NOERROR) 
00555                         return false;
00556                 return true;
00557         }
00558 
00559         /****
00560                 The function return the sting info associated with an error code.
00561         */
00562         static const char* ErrorMsg(int error)
00563         {
00564                 static const char* fbx_error_msg[] =
00565                 {
00566                         "No errors",
00567 
00568                         "Failed to create a KFbxSdkManager",
00569                         "Failed to create a KFbxScene",
00570                         "Failed to create a KFbxImporter",
00571                         "Failed to locate requested file",
00572                         "Failed to import requested file",
00573                 };
00574 
00575                 if(error>6 || error<0) 
00576                         return "Unknown error";
00577                 else 
00578                         return fbx_error_msg[error];
00579         };
00580 
00581         /****
00582                 The open function import info contained in a FBX file into a mesh defined using the VCG standards.
00583                 Parameters:
00584                         - m is the mesh in which you want to load the file info
00585                         - filename is the filename path of a valid FBX file. It could be a relative path or an absolute one.
00586                         - oi is a small structure devoted to contain some feedbacks about the loaded file (like vertex number or face number). Typically you can ignore it. 
00587 
00588                 Semantics:
00589                         If the file has been correctly loaded (i.e. Open function returned a E_NOERROR code, you will find in the mesh m at least:
00590                                 - a vertex position for each vertex
00591                                 - the triangles componing the mesh surface
00592 
00593                         Depending on which type mesh you passed to the function you could also have:
00594                                 - a vertex normal for each vertex
00595                                 - a vertex color (ONLY IF THE FBX FILE HAS ALL THE MATERIALS WITHOUT TEXTURES AT ALL)
00596                                 - a single material for each triangle. We are using the one containing a diffuse texture and/or a diffuse color. 
00597                                 - a UV parameterization for each vertex componing a triangle
00598 
00599                         Please note that if the file is composed by a set of meshes we compact all these meshes in a single one.
00600         */
00601 
00602         static int Open( OpenMeshType &m, const char * filename, Info &oi)
00603         {
00604                 int result = E_NOERROR;
00605                 m.Clear();
00606                 vcg::CallBackPos *cb = oi.cb;
00607 
00608                 KFbxSdkManager* FBXmanager = KFbxSdkManager::Create();
00609                 if (FBXmanager==NULL)
00610                         return E_CANTCREATEFBXMANAGER;
00611                 KFbxScene* FBXscene = KFbxScene::Create(FBXmanager,"");
00612                 if (FBXscene==NULL)
00613                         return E_CANTCREATEFBXSCENE;
00614                 KFbxImporter* importer = KFbxImporter::Create(FBXmanager,"");
00615                 if (importer==NULL)
00616                         return E_CANTCREATEFBXIMPORTER;
00617 
00618                 bool initfile = importer->Initialize(filename);
00619                 if (!initfile)
00620                 {
00621                         printf("Fbx error: %s",importer->GetLastErrorString());         
00622                         return E_CANTFINDFBXFILE;
00623                 }
00624                 bool importfile = importer->Import(FBXscene);
00625                 if (!importfile)
00626                 {
00627                         printf("Fbx error: %s",importer->GetLastErrorString());         
00628                         return E_CANTIMPORTFBXFILE;
00629                 }
00630                 result = ImportScene(m,FBXscene,oi);
00631 
00632                 // if LoadMask has not been called yet, we call it here
00633                 
00634                 if (FBXmanager)
00635                         FBXmanager->Destroy();
00636           return result;
00637         } 
00638 
00639         /****
00640         The LoadMask function gives you a preview of which attributes you will find inside the fbx file. 
00641         It's useful only if you are planning to use a mesh with dynamic attributes.
00642 
00643         Parameters:
00644                 - filename is the filename path of a valid FBX file. It could be a relative path or an absolute one.
00645                 - oi is a small structure devoted to contain some feedbacks about the loaded file (like vertex number or face number). 
00646                 In oi.mask you will find the mask containing the attributes contained in the file. You can query the presence of a specific attribute using the operators on bits.
00647                 ( for example if I want to check if the file contains the vertex normal layer I have to call the LoadMask function and after check if (oi.mask & vcg::tri::io::Mask::IOM_VERTNORMAL) is true).
00648         */
00649 
00650         static int LoadMask(const char * filename, Info &oi)
00651         {
00652                 KFbxSdkManager* FBXmanager = KFbxSdkManager::Create();
00653                 if (FBXmanager==NULL)
00654                         return E_CANTCREATEFBXMANAGER;
00655                 KFbxScene* FBXscene = KFbxScene::Create(FBXmanager,"");
00656                 if (FBXscene==NULL)
00657                         return E_CANTCREATEFBXSCENE;
00658                 KFbxImporter* importer = KFbxImporter::Create(FBXmanager,"");
00659                 if (importer==NULL)
00660                         return E_CANTCREATEFBXIMPORTER;
00661 
00662                 bool initfile = importer->Initialize(filename);
00663                 if (!initfile)
00664                 {
00665                         printf("Fbx error: %s",importer->GetLastErrorString());         
00666                         return E_CANTFINDFBXFILE;
00667                 }
00668                 bool importfile = importer->Import(FBXscene);
00669                 if (!importfile)
00670                 {
00671                         printf("Fbx error: %s",importer->GetLastErrorString());         
00672                         return E_CANTIMPORTFBXFILE;
00673                 }
00674                 LoadMaskNode(FBXscene->GetRootNode(),oi);
00675 
00676                 // if LoadMask has not been called yet, we call it here
00677 
00678                 if (FBXmanager)
00679                         FBXmanager->Destroy();
00680                 return E_NOERROR;
00681         }
00682         
00683 }; // end class
00684 
00685 
00686 #endif 


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:55