如何使用Python向FBX文件添加用户数据并检索已有用户数据
Hey there! I totally get how frustrating it can be to wrap your head around FBX’s user data handling—especially after spending hours digging through docs without clear examples. Let’s break down exactly how to tackle both adding and retrieving user data with Python, using the official Autodesk FBX SDK (the most reliable way to work with FBX files programmatically).
First, make sure you’ve got the FBX Python SDK installed and set up in your environment (it’s included with most Autodesk tools, or you can download it separately). Here’s a complete, commented example that walks you through the process:
from fbx import * def add_fbx_user_data(input_fbx_path, output_fbx_path, target_node_name, data_key, data_value): # Initialize the FBX SDK manager (the core hub for all FBX operations) manager = FbxManager.Create() if not manager: raise Exception("Could not create FBX SDK manager—check your installation!") # Create a scene container to hold the loaded FBX data scene = FbxScene.Create(manager, "WorkingScene") # Load your existing FBX file importer = FbxImporter.Create(manager, "") if not importer.Initialize(input_fbx_path, -1, manager.GetIOSettings()): raise Exception(f"Failed to load FBX file: {importer.GetStatus().GetErrorString()}") if not importer.Import(scene): raise Exception(f"Failed to import scene data: {importer.GetStatus().GetErrorString()}") importer.Destroy() # Clean up the importer once we're done # Find the target node (we'll use the root node if no specific name is given) target_node = scene.GetRootNode() if not target_node_name else scene.FindNodeByName(target_node_name) if not target_node: raise Exception(f"Target node '{target_node_name}' wasn't found in the scene") # Two common ways to add user data—pick whichever fits your use case: ## Option 1: Add a simple custom property (great for basic key-value pairs) # Choose the right data type: FbxStringDT, FbxIntDT, FbxDoubleDT, FbxBoolDT, etc. custom_property = FbxProperty.Create(target_node, FbxStringDT, data_key) custom_property.Set(data_value) # Assign your value to the property ## Option 2: Use FbxUserData for structured, multi-member data # user_data = FbxUserData.Create(manager, "MyStructuredData") # user_data.AddMember(FbxStringDT, data_key, data_value) # target_node.AddUserData(user_data) # Attach the structured data to the node # Save the modified FBX file exporter = FbxExporter.Create(manager, "") if not exporter.Initialize(output_fbx_path, -1, manager.GetIOSettings()): raise Exception(f"Failed to set up exporter: {exporter.GetStatus().GetErrorString()}") if not exporter.Export(scene): raise Exception(f"Failed to save modified FBX: {exporter.GetStatus().GetErrorString()}") exporter.Destroy() # Clean up SDK resources manager.Destroy() print(f"Success! Added user data to {output_fbx_path}") # Example usage: Add an "AssetID" string to the node named "MyCharacterMesh" add_fbx_user_data("my_existing_file.fbx", "my_modified_file.fbx", "MyCharacterMesh", "AssetID", "CHAR-007")
Key Notes for Adding Data:
- Data Types: Match the
Fbx*DTtype to your data (e.g., useFbxIntDTfor integers,FbxDoubleDTfor floats). - Node Targeting: If you don’t know the exact node name, you can traverse the scene’s node tree recursively to find your target.
- Structured Data: Use
FbxUserDataif you need to attach multiple related data points to a single node (like a metadata bundle).
Retrieving data follows a similar workflow—load the file, locate the node, then extract either the custom property or structured user data. Here’s how to do it:
from fbx import * def retrieve_fbx_user_data(fbx_path, target_node_name, data_key): manager = FbxManager.Create() if not manager: raise Exception("Could not create FBX SDK manager") scene = FbxScene.Create(manager, "WorkingScene") # Load the FBX file importer = FbxImporter.Create(manager, "") if not importer.Initialize(fbx_path, -1, manager.GetIOSettings()): raise Exception(f"Failed to load FBX file: {importer.GetStatus().GetErrorString()}") if not importer.Import(scene): raise Exception(f"Failed to import scene data: {importer.GetStatus().GetErrorString()}") importer.Destroy() # Find the target node target_node = scene.GetRootNode() if not target_node_name else scene.FindNodeByName(target_node_name) if not target_node: raise Exception(f"Target node '{target_node_name}' not found") # First, check for a custom property with your key custom_property = target_node.FindProperty(data_key) if custom_property.IsValid(): value = custom_property.Get() print(f"Found custom property '{data_key}': {value}") return value # If no custom property, check for structured FbxUserData user_data_count = target_node.GetUserDataCount() for i in range(user_data_count): user_data = target_node.GetUserData(i) if user_data and user_data.FindMember(data_key): value = user_data.GetMember(data_key) print(f"Found UserData member '{data_key}': {value}") return value # If neither was found print(f"No user data with key '{data_key}' found on node '{target_node_name}'") return None # Example usage: Retrieve the "AssetID" we added earlier retrieved_value = retrieve_fbx_user_data("my_modified_file.fbx", "MyCharacterMesh", "AssetID")
Key Notes for Retrieving Data:
- Check Both Methods: If you’re not sure how the data was added, check both custom properties and
FbxUserData(like the example does). - Node Traversal: If your target node is nested deep in the hierarchy, write a recursive function to iterate through all nodes until you find the right one.
- Error Handling: The example includes basic error handling, but you can expand it to handle edge cases like missing files or invalid data types.
内容的提问来源于stack exchange,提问作者JokerMartini

