Using Python FBX with Eclipse

This topic presents a series of steps which allow you to use the Python FBX module ("fbx") in Eclipse - a cross-platform integrated development environment (IDE). Python code can be written in any text editor, however Eclipse provides an environment to write, debug, and execute Python code.

Installing Python, Java, Eclipse, and PyDev

NOTE:The following steps have been tested on Windows 7 x64 using FBX SDK 2013, Python 2.6, Java JRE 7.4, Eclipse Indigo SR2, and PyDev 2.5.0.2012040618. Some steps may change depending on your operating system and architecture.
  1. Install Python 2.6 or Python 3.1 - Since we will be developing Python programs, we will need the appropriate Python interpreter to execute our Python code. The Python FBX bindings are compiled and distributed for Python 2.6 and Python 3.1.
    1. In this topic, we will be working with Python 2.6, which can be obtained at: http://www.python.org/getit/releases/2.6/. Make sure you download and install the version which matches your operating system and architecture.
    2. Follow the Python FBX installation guide to copy the Python FBX bindings into your Python installation's /site-packages/ directory.
  2. Install Java - The Eclipse IDE is written in Java, so you will first need to download and install the latest version of Java. The following address provides the versions of Java according to each operating system and architecture: http://java.com/en/download/manual.jsp.
  3. Install Eclipse - The latest version of the Eclipse IDE is available at http://www.eclipse.org/downloads/.
    1. Download the "Eclipse Classic" version whose platform and architecture match your Java installation.
    2. Once downloaded, you may simply extract the contents of the downloaded .zip file into the directory of your choosing. For example, extracting to C:\Program Files\ in Windows will create the C:\Program Files\eclipse folder.
    3. Run the eclipse.exe file to open the Eclipse IDE. You will be prompted to select a location for your workspace, which will house your future Eclipse projects.
  4. Install the PyDev Eclipse Plug-in - The Eclipse Classic IDE is typically used to write Java programs. To write Python programs in Eclipse, we will install the PyDev Eclipse plug-in. This plug-in provides useful features for Python development such as syntax highlighting, auto-complete, debugging, execution, interpreter selection, and library/module management.
    1. With Eclipse open, select Help > Install New Software.
    2. In the new window, set the "Work with" field to the following url: http://pydev.org/updates, and press the "Add" button. This url was obtained from: http://pydev.org/download.html.
    3. Set the name of the new repository to "pydev", or another arbitrary name.
    4. The available software table should now include the "PyDev", and "PyDev Mylyn Integration (optional)" checkboxes. Check the "PyDev" checkbox and press the "Next" button.
    5. Proceed with the installation and license review steps and press the "Finish" button, which will prompt Eclipse to install the PyDev plug-in. Eclipse will likely need to restart at the end of the plug-in installation.
  5. Setting up a PyDev Project in Eclipse - The first time you create a PyDev project within your workspace, you must perform the following steps to inform Eclipse of the Python interpreter you want to use.
    1. With Eclipse open, select File > New > Project.
    2. In the Select a wizard window, expand the "PyDev" folder, select "PyDev Project", and press "Next".
    3. In the PyDev Project window, click on the " Please configure an interpreter in the related preferences before proceeding " link near the bottom of the window.
    4. In the Python Interpreters window, press "New".
      1. Enter a name for the Python 2.6 interpreter, for example: "python26".
      2. Press "Browse" and select the installed Python 2.6 interpreter executable. By default on Windows, this file can be found at: C:\Python26\python.exe. Press "Ok" to select the interpreter.
      3. Press "Ok" to add the presented folders to the SYSTEM pythonpath. Press "Ok" again to exit the current window.
    5. In the PyDev Project window, set the Grammar Version drop-down to 2.6., and provide a project name, for example: "myFbxPoject". Press "Finish", and press "Yes" to enable the PyDev perspective in Eclipse.

Using Python FBX with Eclipse

Now that we have created a new PyDev project, we can get to coding our first Python FBX file:

  1. In Eclipse, right-click on your new project folder, and select New > PyDev Module.
  2. Provide a name for your module, for example: "myFbxProgram", and select the "Module: Main" template. You can leave the Package field empty.
  3. Pressing "Finish" will generate the myFbxProgram.py file within your PyDev project, whose contents resemble the following template:
    '''
    Created on ******
    
    @author: ******
    '''
    
    if __name__ == '__main__':
        pass
    NOTE:The if __name__ == '__main__': statement (and all the code below it) is executed when you right-click and select Run As > Python Run on your myFbxProgram.py file. This code can also be debugged by selecting Debug As > Python Run, which will open the Eclipse debugging perspective. For now, the code will do nothing, as illustrated by the "pass" filler keyword. The code surrounded by the three single-quotes is a multi-line comment.
  4. To use the functions provided by the Python FBX bindings, write the following import statement near the top of the file. Eclipse recognizes this module because it was copied it into the Python interpreter's /site-packages/ directory in step 1.2 of the installation above.
    import fbx
  5. We can now add a few lines of code which use the fbx module to create and export a simple scene containing a cubic mesh. Replace the code currently contained in myFbxProgram.py with the following code. As a brief overview, the code below performs the following steps:
    1. Creates an instance of FbxManager, which is used to instantiate the rest of the FBX-related objects.
    2. Creates an empty FbxScene using the FbxManager.
    3. Adds a cube to the scene.
      1. The cube is positioned in the scene using an instance of FbxNode, which is added as a child to the scene's root node.
      2. The vertices and polygons of the actual mesh are defined in an instance of FbxMesh, which is associated as a node attribute to the FbxNode.
    4. Saves the scene to myFbxSaveFile.fbx in the FBX ASCII file format.
    '''
    
     myFbxProgram.py
    
        > Creates a cube in a scene, and saves the scene to 'myFbxSaveFile.fbx' in ASCII format.
        
    '''
    
    import fbx
    
    # A set of vertices which we will use to create a cube in the scene.
    cubeVertices = [ fbx.FbxVector4( -5, -5,  5 ), # 0 - vertex index.
                     fbx.FbxVector4(  5, -5,  5 ), # 1
                     fbx.FbxVector4(  5,  5,  5 ), # 2
                     fbx.FbxVector4( -5,  5,  5 ), # 3
                     fbx.FbxVector4( -5, -5, -5 ), # 4
                     fbx.FbxVector4(  5, -5, -5 ), # 5
                     fbx.FbxVector4(  5,  5, -5 ), # 6
                     fbx.FbxVector4( -5,  5, -5 )] # 7
    
    # The polygons (faces) of the cube.
    polygonVertices = [ (  0,  1,  2,  3 ), # Face 1 - composed of the vertex index sequence: 0, 1, 2, and 3.
                        (  4,  5,  6,  7 ), # Face 2
                        (  8,  9, 10, 11 ), # Face 3 
                        ( 12, 13, 14, 15 ), # Face 4
                        ( 16, 17, 18, 19 ), # Face 5
                        ( 20, 21, 22, 23 )] # Face 6
    
    saveFilename = 'myFbxSaveFile.fbx'
    
    ###############################################################
    # Helper Function(s).                                         #
    ###############################################################
    
    def addCube( pScene ):
        ''' Adds a cubic mesh to the scene. '''
        
        # Obtain a reference to the scene's root node.
        rootNode = pScene.GetRootNode()
        
        # Create a new node in the scene.
        newNode = fbx.FbxNode.Create( pScene, 'myNode' )
        rootNode.AddChild( newNode )
        
        # Create a new mesh node attribute in the scene, and set it as the new node's attribute
        newMesh = fbx.FbxMesh.Create( pScene, 'myMesh' )
        newNode.SetNodeAttribute( newMesh )
        
        # Define the new mesh's control points. Since we are defining a cubic mesh, 
        # there are 4 control points per face, and there are six faces, for a total
        # of 24 control points.
        global cubeVertices 
        newMesh.InitControlPoints( 24 )
        # Face 1
        newMesh.SetControlPointAt( cubeVertices[0], 0 )
        newMesh.SetControlPointAt( cubeVertices[1], 1 )
        newMesh.SetControlPointAt( cubeVertices[2], 2 ) 
        newMesh.SetControlPointAt( cubeVertices[3], 3 ) 
        # Face 2
        newMesh.SetControlPointAt( cubeVertices[1], 4 ) 
        newMesh.SetControlPointAt( cubeVertices[5], 5 )  
        newMesh.SetControlPointAt( cubeVertices[6], 6 ) 
        newMesh.SetControlPointAt( cubeVertices[2], 7 )
        # Face 3
        newMesh.SetControlPointAt( cubeVertices[5], 8 )
        newMesh.SetControlPointAt( cubeVertices[4], 9 )
        newMesh.SetControlPointAt( cubeVertices[7], 10 )
        newMesh.SetControlPointAt( cubeVertices[6], 11 )
        # Face 4
        newMesh.SetControlPointAt( cubeVertices[4], 12 )
        newMesh.SetControlPointAt( cubeVertices[0], 13 )
        newMesh.SetControlPointAt( cubeVertices[3], 14 )
        newMesh.SetControlPointAt( cubeVertices[7], 15 )
        # Face 5
        newMesh.SetControlPointAt( cubeVertices[3], 16 )
        newMesh.SetControlPointAt( cubeVertices[2], 17 )
        newMesh.SetControlPointAt( cubeVertices[6], 18 )
        newMesh.SetControlPointAt( cubeVertices[7], 19 )
        # Face 6
        newMesh.SetControlPointAt( cubeVertices[1], 20 )
        newMesh.SetControlPointAt( cubeVertices[0], 21 )
        newMesh.SetControlPointAt( cubeVertices[4], 22 )
        newMesh.SetControlPointAt( cubeVertices[5], 23 )
        
        # Now that the control points per polygon have been defined, we can create
        # the actual polygons within the mesh.
        global polygonVertices
        for i in range( 0, len( polygonVertices ) ):
            
            newMesh.BeginPolygon( i )
            
            for j in range( 0, len( polygonVertices[i] ) ):
                
                newMesh.AddPolygon( polygonVertices[i][j] )
            
            newMesh.EndPolygon()
    
    def saveScene( pFilename, pFbxManager, pFbxScene, pAsASCII=False ):
        ''' Save the scene using the Python FBX API '''
        exporter = fbx.FbxExporter.Create( pFbxManager, '' )
        
        if pAsASCII:
            #DEBUG: Initialize the FbxExporter object to export in ASCII.
            asciiFormatIndex = getASCIIFormatIndex( pFbxManager )
            isInitialized = exporter.Initialize( pFilename, asciiFormatIndex )
        else:
            isInitialized = exporter.Initialize( pFilename )
        
        if( isInitialized == False ):
            raise Exception( 'Exporter failed to initialize. Error returned: ' + str( exporter.GetStatus().GetErrorString() ) )
        
        exporter.Export( pFbxScene )
        
        exporter.Destroy()
    
    
    def getASCIIFormatIndex( pManager ):
        ''' Obtain the index of the ASCII export format. '''
        # Count the number of formats we can write to.
        numFormats = pManager.GetIOPluginRegistry().GetWriterFormatCount()
        
        # Set the default format to the native binary format.
        formatIndex = pManager.GetIOPluginRegistry().GetNativeWriterFormat()
        
        # Get the FBX format index whose corresponding description contains "ascii".
        for i in range( 0, numFormats ):
            
            # First check if the writer is an FBX writer.
            if pManager.GetIOPluginRegistry().WriterIsFBX( i ):
                
                # Obtain the description of the FBX writer.
                description = pManager.GetIOPluginRegistry().GetWriterFormatDescription( i )
                
                # Check if the description contains 'ascii'.
                if 'ascii' in description:
                    formatIndex = i
                    break
        
        # Return the file format.
        return formatIndex
    
    ###############################################################
    # Main.                                                       #
    ###############################################################
    if __name__ == '__main__':
        
        # Create the required FBX SDK data structures.
        fbxManager = fbx.FbxManager.Create()
        fbxScene = fbx.FbxScene.Create( fbxManager, '' )
        
        # Add a cube to the scene.
        addCube( fbxScene )
        
        # Save the scene.
        saveScene( saveFilename, fbxManager, fbxScene, pAsASCII=True )
        
        ### CLEANUP ###
        #
        # Destroy the fbx manager explicitly, which recursively destroys
        # all the objects that have been created with it. 
        fbxManager.Destroy()
        #
        # Once the memory has been freed, it is good practice to delete
        # the currently invalid references contained in our variables.
        del fbxManager, fbxScene
        #
        ###############
  6. Right-click on the myFbxProgram.py file and select Run As > Python Run
  7. Right-click on the myFbxProject project folder and select Refresh. You will notice that the myFbxSaveFile.fbx file has been added to your project folder. This file contains the scene produced by running myFbxProgram.py.
  8. Right-click on the myFbxSaveFile.fbx file, and select Properties. In the Resource tab, the Location field specifies the path of your newly generated .fbx file. This file can be viewed in any Autodesk program which supports the .fbx file format.