Saving multi merge animations file paths to use later

Hello,

I have a number of animators importing multiple merge animations (just the animations) into a single MB scene on to a character to edit. These merged animations are a number of takes that will eventually be exported including the character back to the same location where they originally merged from.

I wish to save the original merged path location for each merge animation. So I can Python iterate through all the takes when exporting and use their original path location to save.

I’m thinking maybe the take stores this data. If not, create a property if possible on the take with a string value for the path data. I’m not sure how to create a property if it’s possible to do.

Any help would be amazing!

Thanks

This does most of what you need it to do or should give you some help, if you can work around the bugs with the saving to Takes he’s highlighted). Not sure if this has been fixed - I’ve tried in Mobu2018 and issue is present still:

Also here: BasicOperations/CustomProperty.py

1 Like

Try this - works when importing scenes containing just a single take (note this is PySide in Mobu2018 so you’ll need to mod it slightly):

from pyfbsdk import *
from PySide import QtGui
import unicodedata


APP = FBApplication()
DEFAULT_PATH = r"D:\Projects\cascadeur\back_somersault\fbx"
FILE_FILTERS = "FBX (*.fbx);;All Files (*.*)"

selected_filter = "All Files (*.*)"

def unicode_to_ascii(unicode_):
    return unicodedata.normalize('NFKD', unicode_).encode('ascii','ignore')

def add_str_property(node_, path_=""):
    str_prop = node_.PropertyCreate('stored_path', FBPropertyType.kFBPT_charptr, 'String', False, True, None)
    str_prop.Data = path_
    
    
filepaths, _ = QtGui.QFileDialog.getOpenFileNames(None, "Select File", DEFAULT_PATH, FILE_FILTERS, selected_filter)
take_count = len(FBSystem().Scene.Takes)
    
if filepaths:
    for file_ in filepaths:
        asciifile = unicode_to_ascii(file_)
        load_options = FBFbxOptions(True, asciifile)
        APP.FileMerge(asciifile, False, load_options)
        
        # For test purposes, assume there's only a single take in each merged file
        if len(FBSystem().Scene.Takes) > take_count:
            new_take = FBSystem().Scene.Takes[-1]
            add_str_property(new_take, asciifile)
            take_count = len(FBSystem().Scene.Takes)
            
1 Like

quebrado,

Many thanks for your update and generous amount of information. It really did helped! :slight_smile:

I managed to write a tool for our animators to be able to merge multiply takes within a single MB scene to edit. Once edits had been completed, the animator could export all the takes back to their original locations with a single click of a button. 12 take edits would of taken around 10 minutes to export. This new feature does it in 10 seconds. I also, setup FBX settings which I wont go into detail.

Here is a sample of the create attribute code I used. It should help others in the future:

def create_savepath_property(fbobject, path: str) -> None:
    """
    
    Description: When merging animations within a MB scene, being able to save the individual takes source path location will
                  helps to export to the take to it's correct location. Especially when exporting multi takes.
        
    How:         Function creates a Property (attribute) called SavePath with a string argument! 
                 This argument being the takes source path!
    
    Param:
        fbobject =  FBTake.
        path = Property string argument. This will be the takes source path location
        
    """
    # Check property SavePath does not exist to avoid creating a property copy!
    try:
        # update existing property argument if it exists!
        fbobject.PropertyList.Find('SavePath').Data = path
        print(f"\n{fbobject.Name} has the following property arugment updated!")
        print(f"Property: SavePath   Argument: {path}\n\n")
        
    except AttributeError:
        # Create property and argument!
    
        # Explanation of property syntax for fbobject.PropertyCreate()
        
        # Parameters: 
        #   SavePath -  The name of the property. 
        #   FBPropertyType.kFBPT_charptr -  Type of the property see enum FBPropertyType. 
        #   'String' -  DataType of the property is a text define in ANIMATIONNODE_TYPE_??? in fbdata.h. 
        #   False -  To specify if the property can be animated. 
        #   True -  To specify if the property is available as a custom property or dynamic and attached to the object. 
        #   None - Use that param to specify the property that a reference refer to.  
        
        # Create property and argument!    
        fbobject.PropertyCreate('SavePath', FBPropertyType.kFBPT_charptr, 'String', False, True, None)
        fbobject.PropertyList.Find('SavePath').Data = path
        print(f"\n{fbobject.Name} has the following property and argument added!")
        print(f"Property: SavePath   Argument: {path}\n\n")
def get_savepath_argument(fbobject)-> str:
    """
    Description: Querys a take's SavePath property argument, that being a the takes source string path!
                 Note: SavePath needs to be created beforehand. Merging takes will be the best time
                 to create the property and it's argument value. 
        
    param: fbobject, FBTake
    
    """
    try:
        argument = fbobject.PropertyList.Find('SavePath').Data
        return argument
    except AttributeError:
        # Add your code here for errors!
        pass

No problem @Elfis - glad I could be of help in some way