def execute(self, operation, file_path, **kwargs):
        """
        Main hook entry point
        
        :param operation:       String
                                Scene operation to perform
        
        :param file_path:       String
                                File path to use if the operation
                                requires it (e.g. open)
                    
        :returns:               Depends on operation:
                                'current_path' - Return the current scene
                                                 file path as a String
                                all others     - None
        """

        fb_app = FBApplication()

        if operation == "current_path":
            # return the current scene path
            return fb_app.FBXFileName
        elif operation == "open":
            # do new scene as Maya doesn't like opening
            # the scene it currently has open!
            fb_app.FileOpen(file_path)
        elif operation == "save":
            # save the current scene:
            # Note - have to pass the current scene name to
            # avoid showing the save-as dialog
            fb_app.FileSave(fb_app.FBXFileName)
Beispiel #2
0
    def _do_motionbuilder_post_publish(self, work_template, progress_cb):
        """
        Do any Motion Builder post-publish work

        :param work_template:   The primary work template used for the publish
        :param progress_cb:     Callback to be used when reporting progress
        """
        from pyfbsdk import FBApplication

        mb_app = FBApplication()
        
        progress_cb(0, "Versioning up the script")

        # get the current script path:
        original_path = mb_app.FBXFileName
        script_path = os.path.abspath(original_path)

        # increment version and construct new name:
        progress_cb(25, "Finding next version number")
        fields = work_template.get_fields(script_path)
        next_version = self._get_next_work_file_version(work_template, fields)
        fields["version"] = next_version
        new_path = work_template.apply_fields(fields)

        # log info
        self.parent.log_debug("Version up work file %s --> %s..." % (script_path, new_path))

        # save the script:
        progress_cb(75, "Saving the scene file")
        mb_app.FileSave(new_path)

        progress_cb(100)
    def _clear_current_scene_motionbuilder(self):
        """
        Clears the current scene. Does a file -> new.
        Motionbuilder implementation.
        returns False on cancel, true on success.
        """
        from pyfbsdk import FBApplication
        status = True

        fb_app = FBApplication()

        res = QtGui.QMessageBox.question(
            self, "Save your scene?",
            "Your scene has unsaved changes. Save before proceeding?",
            QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
            | QtGui.QMessageBox.Cancel)

        if res == QtGui.QMessageBox.Cancel:
            status = False

        elif res == QtGui.QMessageBox.No:
            # don't save!
            fb_app.FileNew()

        else:
            # save before!
            fb_app.FileSave()
            fb_app.FileNew()

        return status
    def _do_motionbuilder_publish(self, task, work_template, comment,
                                  thumbnail_path, sg_task, progress_cb):
        """
        Publish the main Motion Builder scene

        :param task:            The primary task to publish
        :param work_template:   The primary work template to use
        :param comment:         The publish description/comment
        :param thumbnail_path:  The path to the thumbnail to associate with the published file
        :param sg_task:         The Shotgun task that this publish should be associated with
        :param progress_cb:     A callback to use when reporting any progress
                                to the UI
        :returns:               The path to the file that has been published        
        """
        from pyfbsdk import FBApplication

        mb_app = FBApplication()

        progress_cb(0.0, "Finding scene dependencies", task)
        dependencies = self._motionbuilder_find_additional_scene_dependencies()

        # get scene path
        scene_path = os.path.abspath(mb_app.FBXFileName)

        if not work_template.validate(scene_path):
            raise TankError(
                "File '%s' is not a valid work path, unable to publish!" %
                scene_path)

        # use templates to convert to publish path:
        output = task["output"]
        fields = work_template.get_fields(scene_path)
        fields["TankType"] = output["tank_type"]
        publish_template = output["publish_template"]
        publish_path = publish_template.apply_fields(fields)

        if os.path.exists(publish_path):
            raise TankError("The published file named '%s' already exists!" %
                            publish_path)

        # save the scene:
        progress_cb(10.0, "Saving the scene")
        self.parent.log_debug("Saving the scene...")
        mb_app.FileSave(scene_path)

        # copy the file:
        progress_cb(50.0, "Copying the file")
        try:
            publish_folder = os.path.dirname(publish_path)
            self.parent.ensure_folder_exists(publish_folder)
            self.parent.log_debug("Copying %s --> %s..." %
                                  (scene_path, publish_path))
            self.parent.copy_file(scene_path, publish_path, task)
        except Exception, e:
            raise TankError("Failed to copy file from %s to %s - %s" %
                            (scene_path, publish_path, e))
Beispiel #5
0
def GetControlRigFKEffectors(character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        fkEffectors = []
        for nodeId in FBBodyNodeId.values.itervalues():
            if nodeId not in [
                    FBBodyNodeId.kFBInvalidNodeId, FBBodyNodeId.kFBLastNodeId
            ]:
                effector = character.GetCtrlRigModel(nodeId)
                if effector:
                    fkEffectors.append(effector)
        if fkEffectors == []:
            fkEffectors = None
        return fkEffectors
Beispiel #6
0
def GetControlRigEffectors(character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        controlRigEffectors = GetControlRigFKEffectors(
            character) + GetControlRigIKEffectors(character)
        return controlRigEffectors
    def _do_motionbuilder_pre_publish(self, task, work_template, progress_cb, user_data):
        """
        Do Motion Builder primary pre-publish/scene validation

        :param task:            The primary task to pre-publish
        :param work_template:   The primary work template to use
        :param progress_cb:     A callback to use when reporting any progress
                                to the UI
        :param user_data:       A dictionary containing any data shared by other hooks run prior to
                                this hook. Additional data may be added to this dictionary that will
                                then be accessible from user_data in any hooks run after this one.

        :returns:               A list of any errors or problems that were found
                                during pre-publish
        """
        from pyfbsdk import FBApplication

        mb_app = FBApplication()

        progress_cb(0, "Validating current script", task)

        # get the current script file path:
        script_file = mb_app.FBXFileName
        if script_file:
            script_file = os.path.abspath(script_file)

        # validate it
        script_errors = self._validate_work_file(script_file, work_template, task["output"], progress_cb)

        progress_cb(100)

        return script_errors
    def _do_motionbuilder_pre_publish(self, task, work_template, progress_cb):
        """
        Do Motion Builder primary pre-publish/scene validation

        :param task:            The primary task to pre-publish
        :param work_template:   The primary work template to use
        :param progress_cb:     A callback to use when reporting any progress
                                to the UI
        :returns:               A list of any errors or problems that were found
                                during pre-publish
        """
        from pyfbsdk import FBApplication

        mb_app = FBApplication()

        progress_cb(0, "Validating current script", task)

        # get the current script file path:
        script_file = mb_app.FBXFileName
        if script_file:
            script_file = os.path.abspath(script_file)

        # validate it
        script_errors = self._validate_work_file(script_file, work_template, task["output"], progress_cb)

        progress_cb(100)

        return script_errors
Beispiel #9
0
def CreateNewPose(name=None, character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        if not name:
            name = "New Pose 1"
        pose = FBCharacterPose(name)
        pose.CopyPose(character)
Beispiel #10
0
def PastePose(pose, character=None, pivot=None, match=True):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        poseOptions = PoseOptions(pivot, match)
        FBBeginChangeAllModels()
        pose.PastePose(character, options)
        FBEndChangeAllModels()
        FBSystem().Scene.Evaluate()
Beispiel #11
0
    def _import(self, path, sg_publish_data):
        """
        Import contents of the given file into the scene.
        
        :param path: Path to file.
        :param sg_publish_data: Shotgun data dictionary with all the standard publish fields.
        """
        from pyfbsdk import FBApplication
        
        if not os.path.exists(path):
            raise Exception("File not found on disk - '%s'" % path)
        
        (_, ext) = os.path.splitext(path)
        
        if ext.lower() != ".fbx":
            raise Exception("Unsupported file extension for '%s'. Only FBX files are supported." % path)

        app = FBApplication()
        app.FileMerge(path)
Beispiel #12
0
def GetCharacterEffectorsAndExtensions(character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        effectors = GetControlRigEffectors(character)
        extensions = GetCharacterExtensionObjects(character)
        if not isinstance(effectors, list):
            effectors = [effectors]
        if not isinstance(extensions, list):
            extensions = [extensions]
        return effectors + extensions
Beispiel #13
0
def GetControlRigForCharacter(character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        ctrlRig = character.PropertyList.Find("ControlSet")
        if len(ctrlRig) != 0:
            ctrlRig = ctrlRig[0]
        else:
            ctrlRig = None
        if ctrlRig:
            return ctrlRig
Beispiel #14
0
def AddObjectsToExtension(objList, extension=None, character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if not extension:
        if character:
            extension = FBCharacterExtension(character.LongName + "_Extension")
        else:
            extension = FBCharacterExtension("Character_Extension")
    if not isinstance(objList, list) and not isinstance(
            objList, FBPropertyListComponent):
        objList = [objList]
    for obj in objList:
        FBConnect(obj, extension)
        extension.AddObjectProperties(obj)
        extension.UpdateStancePose()
    if character:
        FBSystem().SuspendMessageBoxes = True
        character.AddCharacterExtension(extension)
        FBSystem().SuspendMessageBoxes = False
    return extension
Beispiel #15
0
    def add_file_to_motionbuilder(self, file_path, shotgun_data):
        """
        Load item into motionbuilder.
        
        This will attempt to merge the loaded file with the scene.
        """
        from pyfbsdk import FBApplication

        if not os.path.exists(file_path):
            self.parent.log_error("The file %s does not exist." % file_path)
            return

        # get the slashes right
        file_path = file_path.replace(os.path.sep, "/")
        
        (path, ext) = os.path.splitext(file_path)
        
        if ext != ".fbx":
            self.parent.log_error("Unsupported file extension for %s. Only FBX files are supported." % file_path)
        else:
            app = FBApplication()
            app.FileMerge(file_path)
Beispiel #16
0
def AdjustmentBlendCharacter(character = None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        take = FBSystem().CurrentTake
        if take.GetLayerCount() > 1:
            characterObjs = GetCharacterEffectorsAndExtensions(character)
            for obj in characterObjs:
                if obj:
                    AdjustmentBlendObject(obj)
        else:
            FBMessageBox("Error...", "No additive layer found. Adjustment blending affects interpolation between keys on the the top most additive layer.", "OK")
    else:
        FBMessageBox("Error...", "No additive layer found. Adjustment blending affects interpolation between keys on the top most additive layer.", "OK")
Beispiel #17
0
def KeyCharacter(character=None, layerName=None, includeScale=False):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        if layerName:
            take = FBSystem().CurrentTake
            layer = take.GetLayerByName(layerName)
            if layer:
                take.SetCurrentLayer(layer.GetLayerIndex())
        characterModels = GetCharacterEffectorsAndExtensions(character)
        if characterModels:
            for obj in characterModels:
                FBSystem().Scene.Evaluate
                KeyObject(obj, includeScale)
    def _do_motionbuilder_post_publish(self, work_template, progress_cb,
                                       user_data):
        """
        Do any Motion Builder post-publish work

        :param work_template:   The primary work template used for the publish
        :param progress_cb:     Callback to be used when reporting progress
        :param user_data:       A dictionary containing any data shared by other hooks run prior to
                                this hook. Additional data may be added to this dictionary that will
                                then be accessible from user_data in any hooks run after this one.
        """
        from pyfbsdk import FBApplication

        mb_app = FBApplication()

        progress_cb(0, "Versioning up the script")

        # get the current script path:
        original_path = mb_app.FBXFileName
        script_path = os.path.abspath(original_path)

        # increment version and construct new name:
        progress_cb(25, "Finding next version number")
        fields = work_template.get_fields(script_path)
        next_version = self._get_next_work_file_version(work_template, fields)
        fields["version"] = next_version
        new_path = work_template.apply_fields(fields)

        # log info
        self.parent.log_debug("Version up work file %s --> %s..." %
                              (script_path, new_path))

        # save the script:
        progress_cb(75, "Saving the scene file")
        mb_app.FileSave(new_path)

        progress_cb(100)
Beispiel #19
0
def GetControlRigIKEffectors(character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        ctrlRig = GetControlRigForCharacter(character)
        ikEffectors = []
        for nodeId in FBEffectorId.values.itervalues():
            if nodeId not in [
                    FBEffectorId.kFBInvalidEffectorId,
                    FBEffectorId.kFBLastEffectorId
            ]:
                effector = ctrlRig.GetIKEffectorModel(nodeId, 0)
                if effector:
                    ikEffectors.append(effector)
        if ikEffectors == []:
            ikEffectors = None
        return ikEffectors
Beispiel #20
0
def GetCharacterExtensionObjects(character=None):
    if not character:
        character = FBApplication().CurrentCharacter
    if character:
        characterExtentionObjects = []
        for ext in FBSystem().Scene.CharacterExtensions:
            attachedChar = ext.PropertyList.Find("AttachedCharacter")
            if len(attachedChar) > 0:
                if attachedChar[0] == character:
                    extObjList = GetObjectsFromExtension(ext)
                    characterExtentionObjects = characterExtentionObjects + extObjList
        if characterExtentionObjects == []:
            characterExtentionObjects = None
        else:
            characterExtentionObjects = list(
                dict.fromkeys(characterExtentionObjects))
        return characterExtentionObjects
Beispiel #21
0
def bootstrap_tank():

    try:
        import tank
    except Exception as e:
        FBMessageBox("Shotgun: Error",
                     "Could not import sgtk! Disabling for now: %s" % e, "Ok")
        return

    if not "TANK_ENGINE" in os.environ:
        FBMessageBox("Shotgun: Error",
                     "Missing required environment variable TANK_ENGINE.",
                     "Ok")
        return

    engine_name = os.environ.get("TANK_ENGINE")
    try:
        context = tank.context.deserialize(os.environ.get("TANK_CONTEXT"))
    except Exception as e:
        FBMessageBox(
            "Shotgun: Error",
            "Could not create context! Shotgun Pipeline Toolkit will be disabled. Details: %s"
            % e,
            "Ok",
        )
        return

    try:
        engine = tank.platform.start_engine(engine_name, context.tank, context)
    except Exception as e:
        FBMessageBox("Shotgun: Error", "Could not start engine: %s" % e, "Ok")
        return

    # if a file was specified, load it now
    file_to_open = os.environ.get("TANK_FILE_TO_OPEN")
    if file_to_open:
        FBApplication.FileOpen(file_to_open)

    # clean up temp env vars
    for var in ["TANK_ENGINE", "TANK_CONTEXT", "TANK_FILE_TO_OPEN"]:
        if var in os.environ:
            del os.environ[var]
Beispiel #22
0
import os

from pyfbsdk import FBFilePopup, FBFilePopupStyle, FBApplication, FBSystem

import create_actor_from_opticals
reload(create_actor_from_opticals)
import map_opticals_to_actor
reload(map_opticals_to_actor)


# Construction of this are expensive, so we create them once.
gSYSTEM = FBSystem()
gAPPLICATION = FBApplication()

# Get take object by it's name.
def GetTakeByName(pName):
    lFound = [lTake for lTake in gSYSTEM.Scene.Takes if lTake.Name==pName]
    if lFound:
        return lFound[0]
    else:
        return None

# Create take with pName.
def createTake(pName):
    #bug in here
    #lTake = FBTake(pName)
    #gSYSTEM.Scene.Components.append(lTake)
    #workaround
    lIsNew = True
    lTakeName = pName
    lTake = GetTakeByName(lTakeName)
Beispiel #23
0
#
# CONFIDENTIAL AND PROPRIETARY
#
# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit
# Source Code License included in this distribution package. See LICENSE.
# By accessing, using, copying or modifying this work you indicate your
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights
# not expressly granted therein are reserved by Shotgun Software Inc.

import os
import sgtk
from sgtk.util.filesystem import ensure_folder_exists

from pyfbsdk import FBApplication, FBFilePopup, FBFilePopupStyle

mb_app = FBApplication()

HookBaseClass = sgtk.get_hook_baseclass()


class MotionBuilderSessionPublishPlugin(HookBaseClass):
    """
    Plugin for publishing an open Motion Builder session.

    This hook relies on functionality found in the base file publisher hook in
    the publish2 app and should inherit from it in the configuration. The hook
    setting for this plugin should look something like this::

        hook: "{self}/publish_file.py:{engine}/tk-multi-publish2/basic/publish_session.py"

    """
Beispiel #24
0
            elif lRotation[0] < 90:
                lRotation[0] = lRotation[0] + 180
            else:
                lRotation[0] = -lRotation[0]
            lRotation[1] = -lRotation[1]
            lRotation[2] = -lRotation[2]
            #Setting the values for the corresponding opposite link
            dstList[i][0].SetVector(lRotation,
                                    FBModelTransformationType.kModelRotation,
                                    True)


## Calling the functions ##

#The current character is the one used
lChar = FBApplication().CurrentCharacter

if not lChar:
    FBMessageBox("Warning", "No character is currently selected.", "Ok")
    print "Script terminated. No character selected."

if lChar:
    if lChar.GetCharacterize():
        FBMessageBox(
            "Warning",
            "Characterization is already locked.\n       Changes will likely be lost.",
            "Ok")

    # User input
    lDirection = FBMessageBox("Mirror Characterization - Select Direction",
                              "(Hips must be facing +Z axis)", "Left to Right",
Beispiel #25
0
    def __init__(self, filePath='', team='', mobu=0, **kwargs):
        super(ParseSchema, self).__init__()
        self.filePath = filePath

        if not filePath:
            if mobu:
                # get sceneName
                from pyfbsdk import FBApplication  # @UnresolvedImport

                self.filePath = Path(FBApplication().FBXFileName.replace(
                    '\\', '/'))
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == '':
                    self.filePath = None
            else:
                try:
                    from pymel.core import sceneName
                except ImportError:
                    sceneName = None
                    logger.errorDialog(
                        "ParseSchema thinks it is in Maya mode, forgot to pass 'mobu=1' arg?"
                    )
                self.filePath = Path(sceneName())
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == 'untitled.ma':
                    self.filePath = None

        # if no team passed, use first team listed in globalVariables.py
        if not team:
            team = gv.teamA

        #Parse the schema file
        relPath = (os.path.dirname(__file__).replace('\\', '/').replace(
            'python/common/fileIO', 'schemas/'))
        self.xmlContent = ET.parse(relPath + team + '.xml')

        #Gather all global headers
        self.coreList = self.xmlContent.getiterator('Core')[0]
        self.characterList = self.xmlContent.getiterator('Character')[0]
        self.environmentList = self.xmlContent.getiterator('Environment')[0]
        self.exportList = self.xmlContent.getiterator('Export')[0]
        self.areaList = self.xmlContent.getiterator('Areas')[0]
        self.mayaList = self.xmlContent.getiterator('Maya')[0]
        self.mobuList = self.xmlContent.getiterator('MoBu')[0]
        self.team = team

        # Read in the asset hub xml section
        if self.team == gv.teamA:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]
            self.assetHubList = self.xmlContent.getiterator('AssetHubUi')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamB:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamC:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")
Beispiel #26
0
def ZeroTrans(transNodes):
    # Subtract the X & Z first keyframe value from
    # the current X & Z positions to zero out their translations
    for node in transNodes:
        if node.Name == "X" or node.Name == "Z":
            keyOffset = node.FCurve.Keys[0].Value
            for key in node.FCurve.Keys:
                key.Value = key.Value - keyOffset


# Create an empty Componenet List to populated with the effector models
compList = FBComponentList()

# Get reference to current character and grab the namespace, if there is one
currChar = FBApplication().CurrentCharacter
if currChar.LongName.rfind(":") != -1:
    nameSpace = currChar.LongName.split(":")[0] + ":"
else:
    nameSpace = ""

# If Char Controls is active run through the Control Rig joint models
# Else apply the calculation to the Skel Hips joint
if currChar.ActiveInput:
    # Find all Effectors, select them, turn down Reach Values, unselect them
    FBFindObjectsByName("*Effector", compList, False, False)
    for comp in compList:
        comp.Selected = True
        if comp.PropertyList.Find("IK Blend T"):
            comp.PropertyList.Find("IK Blend T").Data = 0
        if comp.PropertyList.Find("IK Blend R"):
Beispiel #27
0
    def execute(self, operation, file_path, context, parent_action, **kwargs):
        """
        Main hook entry point

        :operation:     String
                        Scene operation to perform

        :file_path:     String
                        File path to use if the operation
                        requires it (e.g. open)

        :context:       Context
                        The context the file operation is being
                        performed in.

        :parent_action: This is the action that this scene operation is
                        being executed for.  This can be one of:
                        - open_file
                        - new_file
                        - save_file_as
                        - version_up

        :returns:       Depends on operation:
                        'current_path' - Return the current scene
                                         file path as a String
                        'reset'        - True if scene was reset to an empty
                                         state, otherwise False
                        all others     - None
        """
        fb_app = FBApplication()

        if operation == "current_path":
            # return the current scene path
            return fb_app.FBXFileName
        elif operation == "open":
            # do new scene as Maya doesn't like opening
            # the scene it currently has open!
            fb_app.FileOpen(file_path)
        elif operation == "save":
            # save the current scene:
            # Note - have to pass the current scene name to
            # avoid showing the save-as dialog
            fb_app.FileSave(fb_app.FBXFileName)
        elif operation == "save_as":
            fb_app.FileSave(file_path)
        elif operation == "reset":
            """
            Reset the scene to an empty state
            """

            while True:
                # Note, there doesn't appear to be any way to query if
                # there are unsaved changes through the MotionBuilder
                # Python API.  Therefore we just assume there are and
                # prompt the user anyway!
                res = QtGui.QMessageBox.question(
                    None, "Save your scene?",
                    "Your scene has unsaved changes. Save before proceeding?",
                    QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
                    | QtGui.QMessageBox.Cancel)

                if res == QtGui.QMessageBox.Cancel:
                    # stop now!
                    return False
                elif res == QtGui.QMessageBox.No:
                    break
                else:
                    # save the file first
                    # Note - have to pass the current scene name to
                    # avoid showing the save-as dialog
                    if fb_app.FileSave(fb_app.FBXFileName):
                        break

            # perform file-new
            fb_app.FileNew()
            return True
Beispiel #28
0
        return

    engine_name = os.environ.get("TANK_ENGINE")
    try:
        context = tank.context.deserialize(os.environ.get("TANK_CONTEXT"))
    except Exception, e:
        FBMessageBox(
            "Shotgun: Error",
            "Could not create context! Shotgun Pipeline Toolkit will be disabled. Details: %s"
            % e, "Ok")
        return

    try:
        engine = tank.platform.start_engine(engine_name, context.tank, context)
    except Exception, e:
        FBMessageBox("Shotgun: Error", "Could not start engine: %s" % e, "Ok")
        return

    # if a file was specified, load it now
    file_to_open = os.environ.get("TANK_FILE_TO_OPEN")
    if file_to_open:
        FBApplication.FileOpen(file_to_open)

    # clean up temp env vars
    for var in ["TANK_ENGINE", "TANK_CONTEXT", "TANK_FILE_TO_OPEN"]:
        if var in os.environ:
            del os.environ[var]


bootstrap_tank()
# Exports snapshotted data from a motion builder scene into BitSquid's
# internal data format. Each take in the scene is exported to a separate
# file in a directory selected by the user.

from pyfbsdk import FBSystem, FBApplication, FBFbxOptions, FBLabel, ShowTool, FBAddRegionParam, FBAttachType, FBImageContainer, FBList, FBFileFormatAndVersion, FBButton, FBButtonStyle, FBTextJustify, FBFolderPopup, FBFilePopup, FBFilePopupStyle, FBPlayerControl, FBTime, FBMatrix, FBModelTransformationMatrix, FBProgress

from pyfbsdk_additions import ToolList, DestroyToolByName, CreateUniqueTool, HBoxLayout

import re, os, os.path, sys, _winreg

# Global objects and settings
TOOL_NAME = "BitSquid Exporter"
SYSTEM = FBSystem()
APP = FBApplication()
SCENE = FBSystem().Scene


# Class that handles updating the motion builder progress bar based on current take and frame
# number. Typical usage:
#
#	progress.begin()				# starts displaying the progress bar
#	progress.takes = 10				# sets the number of takes to export
#	for t in takes:
#		progress.frames = 100		# sets the number of frames in the current take
#		for f in frames:
#			# export
#			progress.next_frame()	# tells the progress bar that one frame has been processed
#		progress.next_take()		# tells the progerss bar that one take has been processed
class Progress:
    def __init__(self):
        self.progress = FBProgress()