Search code examples
c++modelautodeskfbx

I can't use fbx sdk (2020) to save a fbx with embed texture


I use cloneManager to clone one of the groups in one scene that contains 2-3 meshes and their materials and textures, and then I want to export it to another scene as fbx, which contains the materials and embedded textures.

I've isolated some of the models I want, but they don't have textures or textures

I saw that the mesh in the new scene I cloned already contained the texture path, which pointed to an fbm path, but I still couldn't see the texture when I opened it. And the fbm files that belong to this new fbx model are not automatically created.

I have two questions:

Did I actually clone the texture? Or did I actually export the texture?

Here is my code

Thanks

`

#include <iostream>
#include "Common.h"
#include "Util.h"
#include <string>
#include <fbxsdk/core/fbxobject.h>
#include "fbxsdk.h"

using namespace std;

int main(int, char **) {
    std::cout << "Hello, Start!\n";
    FbxManager *lSdkManager = nullptr;
    FbxScene *lScene = nullptr;

    // Prepare the FBX SDK.
    InitializeSdkObjects(lSdkManager, lScene);
    string lFilePath = "/Users/Downloads/new_scene1_0.fbx";
    string targetPath = "/Users/CLionProjects/CMakeLists/test/";
    LoadScene(lSdkManager, lScene, lFilePath.c_str());

    FbxNode *rootNode = lScene->GetRootNode();
    int childCount = rootNode->GetChildCount();
    for (int i = 0; i < 1; i++) {
        auto pScene = FbxScene::Create(lSdkManager, "My Scene");
        auto node = rootNode->GetChild(i);

        // clone
        CloneAndSetting(lScene, pScene, node);
        auto pSceneRoot = pScene->GetRootNode();

        GetNodeNameAndAttributeTypeName(pSceneRoot);
        GetDefaultTranslationInfo(pSceneRoot);
        GetNodeVisibility(pSceneRoot);

        std::cout << "pScene srcCount: " << pScene->GetSrcObjectCount() << "\n";
        std::cout << "pScene geoCount: " << pScene->GetGeometryCount() << "\n";
        std::cout << "pScene matCount: " << pScene->GetMaterialCount() << "\n";
        std::cout << "pScene nodeCount: " << pScene->GetNodeCount() << "\n";

        GetNodeCountInfo(pSceneRoot);

        // find the first group node
        FbxObject *shapeNode = nullptr;
        for (int j = 0; j < pSceneRoot->GetSrcObjectCount(); ++j) {
            auto obj = pSceneRoot->GetSrcObject(j);
            string name = obj->GetName();
            if (name.find("Shape") != string::npos) {
                shapeNode = obj;
            }
        }

        // disconnect some connection, and connect the shape to root
        pSceneRoot->DisconnectAllSrcObject();
        GetNodeCountInfo(pSceneRoot);
        //shapeNode->DisconnectAllDstObject();
        shapeNode->ConnectDstObject(pSceneRoot);
        GetNodeCountInfo(pSceneRoot);

        for (int j = 0; j < pSceneRoot->GetChildCount(); j++) {
            auto shape = pSceneRoot->GetChild(j);
            std::cout << "c name: " << shape->GetName() << "\n";
            std::cout << "c type: " << shape->GetTypeName() << "\n";
            std::cout << "c dst: " << shape->GetDstObject()->GetName() << "\n";
            
            int groupCount = shape->GetChildCount();
            for (int k = 0; k < groupCount; k++) {
                auto group = shape->GetChild(k);
                auto groupChildCount = group->GetChildCount();
                
                for (int l = 0; l < groupChildCount; l++) {
                    FbxNode *meshNode = group->GetChild(l);
                    FbxSurfaceMaterial *meshMat = meshNode->GetMaterial(0);
                    FbxProperty meshMatProp = meshMat->FindProperty(FbxSurfaceMaterial::sDiffuse);
                    string texPath = nullptr;

                    
                    int layeredTextureCount = meshMatProp.GetSrcObjectCount<FbxLayeredTexture>();
                    if (layeredTextureCount != 0) {
                        std::cout << "link layer" << "\n";
                        auto *layeredTexture = meshMatProp.GetSrcObject<FbxLayeredTexture>();
                        for (int m = 0; m < layeredTexture->GetSrcObjectCount<FbxTexture>(); m++) {
                            auto *fbxFileTexture = FbxCast<FbxFileTexture>(layeredTexture->GetSrcObject<FbxTexture>(m));
                            string fileName = fbxFileTexture->GetFileName();
                            texPath = fileName;
                        }
                    }

                    
                    int textureCount = meshMatProp.GetSrcObjectCount<FbxTexture>();
                    if (textureCount != 0) {
                        std::cout << "link mat" << "\n";
                        auto *fbxTexture = FbxCast<FbxTexture>(meshMatProp.GetSrcObject<FbxTexture>(0));
                        auto *fbxFileTexture = FbxCast<FbxFileTexture>(fbxTexture);
                        string fileName = fbxFileTexture->GetFileName();
                        std::cout << "fileName: " << fileName << "\n";
                        texPath = fileName;
                    }
                    meshNode->GetMesh()->Set
                }
            }
        }
        for (int j = 0; j < pSceneRoot->GetSrcObjectCount(); j++) {
            std::cout << "s name: " << pSceneRoot->GetSrcObject(j)->GetName() << "\n";
            std::cout << "s type: " << pSceneRoot->GetSrcObject(j)->GetTypeName() << "\n";
            std::cout << "s dst: " << pSceneRoot->GetSrcObject(j)->GetDstObject()->GetName() << "\n";
        }

        std::cout << "-----start generate------\n";
        string meshName = node->GetName();
        meshName = targetPath + meshName + ".fbx";
        lSdkManager->GetIOSettings()->SetBoolProp(EXP_FBX_EMBEDDED, true);
        SaveScene(lSdkManager, pScene, meshName.c_str());
        pScene->Destroy();
        std::cout << "----" << i << " end----\n";

    }
}

`


Solution

  • To export a scene and have its media embedded within the exported FBX file, the binary (or native) FBX file format identifier must be specified in the call to FbxExporter::Initialize().

    // ... Initialize the required objects and variables ...
    // Set the FbxIOSettings EXP_FBX_EMBEDDED property to true.
    (*(lSdkManager->GetIOSettings())).SetBoolProp(EXP_FBX_EMBEDDED, true);
    
    // Get the appropriate file format.
    int lFileFormat = lSdkManager->GetIOPluginRegistry()- 
    >GetNativeWriterFormat();
    
    // Initialize the exporter to embed the scene's media into the exported file.
    bool lExportStatus = lExporter->Initialize(lFilename, lFileFormat, 
    lSdkManager->GetIOSettings());
    
    // ... Export the scene ...