FBX SDK Programmer's Guide > Getting Started >

# Your First FBX SDK Program

This topic provides a basic overview of your first FBX SDK program.

For the purposes of this quick guide, the program will use the statically linked version of the FBX SDK. For additional information on how to install and configure the FBX SDK for your environment, see Installing and Configuring.

The following FBX SDK program will provide an overview on how to:

1. Instantiate an FBX SDK memory management object (FbxManager)
2. Import the contents of an FBX file into a scene (FbxIOSettings, FbxImporter, FbxScene)
3. Traverse the element hierarchy of a scene. (FbxScene, FbxNode, FbxNodeAttribute)
4. Access and print basic information about the elements of a scene. (FbxNode, FbxNodeAttribute, FbxString)

Managing Objects

Related topics:

- FBX SDK Object Model

The majority of objects manipulated by the FBX SDK are instantiated with a reference to the SDK's memory manager object (FbxManager). It is usually one of the first objects to be created in a program which uses the FBX SDK, and it is instantiated with the FbxManager::Create() function. A program only requires one instance of FbxManager. When an instance of FbxManager is destroyed via the FbxManager::Destroy() method, all the other FBX SDK objects which were created with it are also destroyed.

    #include <fbxsdk.h>

    // ...

    /**
     * Main function - loads the hard-coded fbx file,
     * and prints its contents in an xml format to stdout.
     */
    int main(int argc, char** argv) {

        // Change the following filename to a suitable filename value.
        const char* lFilename = "file.fbx";

        // Initialize the sdk manager. This object handles all our memory management.
        FbxManager* lSdkManager = FbxManager::Create();

Importing the Contents of an FBX File

Related topics:

- Supported File Formats
- I/O Settings
- Importing a Scene

To import the contents of an FBX file, a FbxIOSettings object and a FbxImporter object must be created. A FbxImporter object is initialized by providing the filename of the file we want to import along with a FbxIOSettings object which has been appropriately configured to suit our importing needs (see I/O Settings).

        // Create the io settings object.
        FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT);
        lSdkManager->SetIOSettings(ios);

        // Create an importer using our sdk manager.
        FbxImporter* lImporter = FbxImporter::Create(lSdkManager,"");

        // Use the first argument as the filename for the importer.
        if(!lImporter->Initialize(lFilename, -1, lSdkManager->GetIOSettings())) {
            printf("Call to FbxImporter::Initialize() failed.\n");
            printf("Error returned: %s\n\n", lImporter->GetLastErrorString());
            exit(-1);
        }

The FbxImporter object populates a provided FbxScene object with the elements contained in the FBX file. Observe that the FbxScene::Create() function is passed an empty string as its second parameter. Objects created in the FBX SDK can be given arbitrary, non-unique names, which allow the user or other programs to identify the object after it has been exported. After the FbxScene is populated, the FbxImporter can be safely destroyed.

        // Create a new scene so it can be populated by the imported file.
        FbxScene* lScene = FbxScene::Create(lSdkManager,"myScene");

        // Import the contents of the file into the scene.
        lImporter->Import(lScene);

        // The file has been imported; we can get rid of the importer.
        lImporter->Destroy();

Exploring the Scene

Related topics:

- FBX Scenes
- FBX Nodes
- FBX Node Attributes
- Merging Two Scenes

The FbxScene object acts as a container for elements existing within the scene. Observe that there can only be one FbxScene object per imported or exported file. A scene can contain a variety of elements including: meshes, lights, cameras, skeletons, and nurbs (to name but a few). The elements of a FbxScene are organized in a hierarchical tree of FbxNodes. The root node of a scene is accessed via FbxScene::GetRootNode(). Note that the root node of a scene is not saved when the scene is exported to a file; only its children are saved. The children of a node can be accessed via FbxNode::GetChild(). Likewise, the parent of a node can be accessed via FbxNode::GetParent(). Conceptually, a FbxNode acts as a container for one or more scene elements. For example, one FbxNode in the scene can contain a camera, whereas another FbxNode can contain a mesh. In the FBX SDK, scene elements such as meshes, lights, cameras, skeletons, nurbs, animation curves, etc, are defined by classes derived from FbxNodeAttribute. There can be more than one FbxNodeAttribute per FbxNode.

        // Print the nodes of the scene and their attributes recursively.
        // Note that we are not printing the root node, because it should
        // not contain any attributes.
        FbxNode* lRootNode = lScene->GetRootNode();
        if(lRootNode) {
            for(int i = 0; i < lRootNode->GetChildCount(); i++)
                PrintNode(lRootNode->GetChild(i));
        }
        // Destroy the sdk manager and all other objects it was handling.
        lSdkManager->Destroy();

A FbxNode provides access to its local translation (FbxNode::LclTranslation), rotation (FbxNode::LclRotation), and scaling (FbxNode::LclScaling) properties. These properties represent the transformations applied to the parent node's position, orientation, and scale to obtain the current node's position, orientation, and scale.

    /**
     * Print a node, its attributes, and all its children recursively.
     */
    void PrintNode(FbxNode* pNode) {
        PrintTabs();
        const char* nodeName = pNode->GetName();
        fbxDouble3 translation = pNode->LclTranslation.Get();
        fbxDouble3 rotation = pNode->LclRotation.Get();
        fbxDouble3 scaling = pNode->LclScaling.Get();

        // print the contents of the node.
        printf("<node name='%s' translation='(%f, %f, %f)' rotation='(%f, %f, %f)' scaling='(%f, %f, %f)'>\n",
            nodeName,
            translation[0], translation[1], translation[2],
            rotation[0], rotation[1], rotation[2],
            scaling[0], scaling[1], scaling[2]
            );
        numTabs++;

        // Print the node's attributes.
        for(int i = 0; i < pNode->GetNodeAttributeCount(); i++)
            PrintAttribute(pNode->GetNodeAttributeByIndex(i));

        // Recursively print the children nodes.
        for(int j = 0; j < pNode->GetChildCount(); j++)
            PrintNode(pNode->GetChild(j));

        numTabs--;
        PrintTabs();
        printf("</node>\n");
    }

Your First Program

    #include <fbxsdk.h>

    /* Tab character ("\t") counter */
    int numTabs = 0;

    /**
     * Print the required number of tabs.
     */
    void PrintTabs() {
        for(int i = 0; i < numTabs; i++)
            printf("\t");
    }

    /**
     * Return a string-based representation based on the attribute type.
     */
    FbxString GetAttributeTypeName(FbxNodeAttribute::EAttributeType type) {
        switch(type) {
            case FbxNodeAttribute::eUNIDENTIFIED: return "unidentified";
            case FbxNodeAttribute::eNULL: return "null";
            case FbxNodeAttribute::eMARKER: return "marker";
            case FbxNodeAttribute::eSKELETON: return "skeleton";
            case FbxNodeAttribute::eMESH: return "mesh";
            case FbxNodeAttribute::eNURB: return "nurb";
            case FbxNodeAttribute::ePATCH: return "patch";
            case FbxNodeAttribute::eCAMERA: return "camera";
            case FbxNodeAttribute::eCAMERA_STEREO:    return "stereo";
            case FbxNodeAttribute::eCAMERA_SWITCHER: return "camera switcher";
            case FbxNodeAttribute::eLIGHT: return "light";
            case FbxNodeAttribute::eOPTICAL_REFERENCE: return "optical reference";
            case FbxNodeAttribute::eOPTICAL_MARKER: return "marker";
            case FbxNodeAttribute::eNURBS_CURVE: return "nurbs curve";
            case FbxNodeAttribute::eTRIM_NURBS_SURFACE: return "trim nurbs surface";
            case FbxNodeAttribute::eBOUNDARY: return "boundary";
            case FbxNodeAttribute::eNURBS_SURFACE: return "nurbs surface";
            case FbxNodeAttribute::eSHAPE: return "shape";
            case FbxNodeAttribute::eLODGROUP: return "lodgroup";
            case FbxNodeAttribute::eSUBDIV: return "subdiv";
            default: return "unknown";
        }
    }

    /**
     * Print an attribute.
     */
    void PrintAttribute(FbxNodeAttribute* pAttribute) {
        if(!pAttribute) return;

        FbxString typeName = GetAttributeTypeName(pAttribute->GetAttributeType());
        FbxString attrName = pAttribute->GetName();
        PrintTabs();
        // Note: to retrieve the chararcter array of a FbxString, use its Buffer() method.
        printf("<attribute type='%s' name='%s'/>\n", typeName.Buffer(), attrName.Buffer());
    }

    /**
     * Print a node, its attributes, and all its children recursively.
     */
    void PrintNode(FbxNode* pNode) {
        PrintTabs();
        const char* nodeName = pNode->GetName();
        fbxDouble3 translation = pNode->LclTranslation.Get();
        fbxDouble3 rotation = pNode->LclRotation.Get();
        fbxDouble3 scaling = pNode->LclScaling.Get();

        // print the contents of the node.
        printf("<node name='%s' translation='(%f, %f, %f)' rotation='(%f, %f, %f)' scaling='(%f, %f, %f)'>\n",
            nodeName,
            translation[0], translation[1], translation[2],
            rotation[0], rotation[1], rotation[2],
            scaling[0], scaling[1], scaling[2]
            );
        numTabs++;

        // Print the node's attributes.
        for(int i = 0; i < pNode->GetNodeAttributeCount(); i++)
            PrintAttribute(pNode->GetNodeAttributeByIndex(i));

        // Recursively print the children nodes.
        for(int j = 0; j < pNode->GetChildCount(); j++)
            PrintNode(pNode->GetChild(j));

        numTabs--;
        PrintTabs();
        printf("</node>\n");
    }

    /**
     * Main function - loads the hard-coded fbx file,
     * and prints its contents in an xml format to stdout.
     */
    int main(int argc, char** argv) {

        // Change the following filename to a suitable filename value.
        const char* lFilename = "file.fbx";

        // Initialize the sdk manager. This object handles all our memory management.
        FbxManager* lSdkManager = FbxManager::Create();

        // Create the io settings object.
        FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT);
        lSdkManager->SetIOSettings(ios);

        // Create an importer using our sdk manager.
        FbxImporter* lImporter = FbxImporter::Create(lSdkManager,"");

        // Use the first argument as the filename for the importer.
        if(!lImporter->Initialize(lFilename, -1, lSdkManager->GetIOSettings())) {
            printf("Call to FbxImporter::Initialize() failed.\n");
            printf("Error returned: %s\n\n", lImporter->GetLastErrorString());
            exit(-1);
        }

        // Create a new scene so it can be populated by the imported file.
        FbxScene* lScene = FbxScene::Create(lSdkManager,"myScene");

        // Import the contents of the file into the scene.
        lImporter->Import(lScene);

        // The file has been imported; we can get rid of the importer.
        lImporter->Destroy();

        // Print the nodes of the scene and their attributes recursively.
        // Note that we are not printing the root node, because it should
        // not contain any attributes.
        FbxNode* lRootNode = lScene->GetRootNode();
        if(lRootNode) {
            for(int i = 0; i < lRootNode->GetChildCount(); i++)
                PrintNode(lRootNode->GetChild(i));
        }
        // Destroy the sdk manager and all other objects it was handling.
        lSdkManager->Destroy();
        return 0;
    }