BlenderFBXExporter 導出fbx被修改問題

1) 解決增加A節點的問題

https://github.com/A-Ribeiro/CustomBlenderFBXExporter

2)找出blendshape 不一致,生成blendshape key name映射map 文件compare.txt

C:\Users\49938\Documents\DazToUnreal\zhang01\UpdatedFBX\zhang01_fix7.fbx
C:\Users\49938\Documents\DazToUnreal\zhang01\UpdatedFBX\zhang01.fbx
C:\Users\49938\Documents\DazToUnreal\zhang01\UpdatedFBX\compare.txt

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
BlendShape差異可視化報告生成器
生成HTML格式的BlendShape比較報告
"""from fbx import *
import sys
import os
import json
from datetime import datetimedef InitializeSdk():"""初始化SDK"""manager = FbxManager.Create()ios = FbxIOSettings.Create(manager, IOSROOT)manager.SetIOSettings(ios)return managerdef LoadFBX(manager, filename):"""加載FBX文件"""scene = FbxScene.Create(manager, "")importer = FbxImporter.Create(manager, "")if not importer.Initialize(filename, -1, manager.GetIOSettings()):return Noneif not importer.Import(scene):importer.Destroy()return Noneimporter.Destroy()return scenedef SafeCastToBlendShape(deformer):"""安全地將變形器轉換為 BlendShape 對象"""try:if hasattr(FbxBlendShape, 'Cast'):return FbxBlendShape.Cast(deformer)else:return deformerexcept Exception as e:print(f"類型轉換錯誤: {e}")return deformerdef ExtractBlendShapeKeys(scene):"""提取場景中所有的 BlendShape Key Names"""blendshape_data = {'keys': [],'meshes': {},  # 記錄每個mesh的blendshape信息'total_channels': 0}def TraverseNode(node):try:mesh = node.GetMesh()if mesh:mesh_name = node.GetName()mesh_blendshapes = []deformer_count = mesh.GetDeformerCount()for i in range(deformer_count):deformer = mesh.GetDeformer(i)deformer_type = deformer.GetDeformerType()if deformer_type == FbxDeformer.eBlendShape:blend_shape = SafeCastToBlendShape(deformer)try:channel_count = blend_shape.GetBlendShapeChannelCount()blendshape_data['total_channels'] += channel_countfor j in range(channel_count):channel = blend_shape.GetBlendShapeChannel(j)if channel:channel_name = channel.GetName()target_shape_count = channel.GetTargetShapeCount()if target_shape_count > 0:key_info = {'name': channel_name,'mesh': mesh_name,'target_count': target_shape_count}blendshape_data['keys'].append(key_info)mesh_blendshapes.append(channel_name)except Exception as e:print(f"處理 BlendShape 通道時出錯: {e}")if mesh_blendshapes:blendshape_data['meshes'][mesh_name] = mesh_blendshapes# 遞歸遍歷子節點for i in range(node.GetChildCount()):TraverseNode(node.GetChild(i))except Exception as e:print(f"處理節點 '{node.GetName()}' 時出錯: {e}")root_node = scene.GetRootNode()if root_node:TraverseNode(root_node)return blendshape_datadef process_blendshape_diff(file_a, file_b, output_file):"""生成HTML比較報告"""# 初始化SDKmanager = InitializeSdk()# 加載文件scene_a = LoadFBX(manager, file_a)scene_b = LoadFBX(manager, file_b)if not scene_a or not scene_b:print("錯誤: 無法加載文件")manager.Destroy()return False# 獲取BlendShape信息print("正在分析文件A的BlendShape...")blendshapes_a = ExtractBlendShapeKeys(scene_a)print("正在分析文件B的BlendShape...")blendshapes_b = ExtractBlendShapeKeys(scene_b)blendshapes_a['keys']# 創建BlendShape名稱列表names_a = [key['name'] for key in blendshapes_a['keys']]names_b = [key['name'] for key in blendshapes_b['keys']]if len(names_a) != len(names_b):print("? 錯誤: 文件A和文件B的BlendShape數量不一致")manager.Destroy()return Falseelse:with open(output_file, 'w', encoding='utf-8') as f:print("文件A和文件B的BlendShape數量一致\n")# in rangefor i in range(len(names_a)):if names_a[i] != names_b[i]:f.write(f"{names_a[i]}|{names_b[i]}\n")# 清理manager.Destroy()return Truedef main():"""主函數"""if len(sys.argv) < 3:print("🎭 BlendShape差異可視化報告生成器")print("\n📖 使用方法:")print("  python fbx_blendshape_diff_visualizer.py <fbxA> <fbxB> [blendshape_comparison.txt]")print("\n📋 參數:")print("  fbxA: 第一個FBX文件")print("  fbxB: 第二個FBX文件")print("  output.html: 可選 ")sys.exit(1)file_a = sys.argv[1]file_b = sys.argv[2]output_file = sys.argv[3] if len(sys.argv) > 3 else "blendshape_comparison.txt"# 檢查文件if not os.path.exists(file_a):print(f"? 錯誤: 文件不存在 - {file_a}")sys.exit(1)if not os.path.exists(file_b):print(f"? 錯誤: 文件不存在 - {file_b}")sys.exit(1)print("🚀 開始分析BlendShape差異...")print(f"📁 文件A: {file_a}")print(f"📁 文件B: {file_b}")process_blendshape_diff(file_a, file_b, output_file)if __name__ == "__main__":main()

?3)在blender里執行腳本修改blendshape key name


import bpy
import sys
import osdef rename_shape_keys_by_map(object_name, map_dict):"""批量重命名指定物體的形狀鍵,移除指定前綴"""# 獲取指定的物體obj = bpy.data.objects.get(object_name)if not obj:print(f"Error: Object '{object_name}' not found.")return -1if not obj.data or not hasattr(obj.data, 'shape_keys') or not obj.data.shape_keys:print(f"Error: Object '{object_name}' has no shape keys.")return -1shape_keys = obj.data.shape_keys.key_blocksrenamed_count = 0# 從第二個key開始遍歷 (跳過'Basis'基礎鍵)for key in shape_keys[1:]:if key.name in map_dict:# 保存原名稱用于打印old_name = key.name# 獲取新名稱new_name = map_dict[key.name]# 重命名key.name = new_nameprint(f"Renamed '{old_name}' to '{new_name}'")renamed_count += 1print(f"\nBatch renaming complete! Renamed {renamed_count} shape keys.")return renamed_countdef batch_rename_all_objects():"""遍歷場景中的所有物體,對每個物體執行形狀鍵重命名操作對每個物體名稱取'.'前面的部分作為基礎名稱,然后移除'_facs_ctrl'和'_facs_bs'前綴"""map_path = r"C:\Users\49938\Documents\DazToUnreal\zhang01\UpdatedFBX\compare.txt"if not os.path.exists(map_path):print(f"Error: Map file '{map_path}' does not exist.")return -1# 讀取文件的所有行with open(map_path, 'r', encoding='utf-8') as file:lines = file.readlines()# 創建一個字典來存儲舊名稱和新名稱的映射map_dict = {}for line in lines:# 去除行首尾的空白字符line = line.strip()if not line:continue  # 跳過空行# 分割行,假設格式為 "舊名稱|新名稱"parts = line.split('|')if len(parts) == 2:old_name, new_name = partsmap_dict[old_name] = new_nameelse:print(f"Warning: Line '{line}' is not in the expected format 'old_name new_name'. Skipping.")# 獲取場景中的所有物體all_objects = bpy.data.objectsprint("Starting batch rename for all objects in scene...")print("=" * 50)for obj in all_objects:# 獲取物體名稱,取'.'前面的部分object_name = obj.namebase_name = object_name.split('.')[0]print(f"\nProcessing object: '{object_name}' (base: '{base_name}')")# 對每個物體調用兩次重命名函數rename_shape_keys_by_map(object_name, map_dict)print("\n" + "=" * 50)print("Batch processing complete!")print("=" * 50)
batch_rename_all_objects() 

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/913097.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/913097.shtml
英文地址,請注明出處:http://en.pswp.cn/news/913097.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI時代下的IT服務管理轉型:趨勢、挑戰與破局之道

近年來&#xff0c;人工智能&#xff08;AI&#xff09;與自動化技術的迅猛發展&#xff0c;正以前所未有的速度重塑企業運營的各個層面。特別是在IT服務管理&#xff08;ITSM&#xff09;領域&#xff0c;AI的介入不僅提高了問題響應效率&#xff0c;也推動了組織從“被動響應…

三體融合實戰:Django+訊飛星火+Colossal-AI的企業級AI系統架構

目錄 技術棧關鍵詞&#xff1a;Django 5.0 訊飛星火4.0Ultra Colossal-AI 1.2 WebSocket 聯邦學習 ? 核心架構設計 &#x1f6e0;? 一、Django深度集成訊飛星火API&#xff08;免費版&#xff09; 1. 獲取API憑證 2. 流式通信改造&#xff08;解決高并發阻塞&#xff09…

多模態數據融合預警:從IoT傳感器到衛星監測的可視化方案升級

你有沒有想過&#xff0c;為什么有些城市在暴雨來臨時能提前數小時發布內澇預警&#xff0c;而有些地方卻只能“等水來了才反應”&#xff1f; 背后的關鍵&#xff0c;就是多模態數據融合預警系統——它把來自IoT傳感器、無人機、地面雷達、氣象站、甚至衛星的數據整合在一起&a…

面試八股---css

2、css 2.1 說說你對盒子模型的理解 是什么 當對一個文檔進行布局&#xff08;layout&#xff09;的時候&#xff0c;瀏覽器的渲染引擎會根據標準之一的 CSS 基礎框盒模型&#xff08;CSS basic box model&#xff09;&#xff0c;將所有元素表示為一個個矩形的盒子&#xf…

day52-硬件學習之RTC及ADC

一、RTCRTC&#xff08;實時時鐘&#xff09;&#xff1a;非易失性在IMX6ULL內部SNVS&#xff08;安全的非易失性存儲器&#xff09;提供RTC功能&#xff1b;原理圖&#xff1a;二、ADC 2.1 基本概念ADC(模擬數字轉換器)&#xff1a;用于將連續變化的模擬信號轉換為離散的數字信…

Web 項目如何自動化測試?

Web 項目的自動化測試可以通過 UI自動化 和 接口自動化 結合實現&#xff0c;提高測試效率和覆蓋率。以下是關鍵方法和工具&#xff1a; 【自動化測試】從基礎到實戰基于Pytest自動化/python自動化的詳細教程&#xff01;1. UI自動化測試&#xff08;前端交互&#xff09; 適用…

Java連接阿里云MaxCompute例

要使用Java連接阿里云MaxCompute&#xff08;原名ODPS&#xff09;數據庫&#xff0c;您可以遵循以下步驟進行配置和編程&#xff1a; 1. 添加依賴 確保您的項目中包含了MaxCompute JDBC驅動的依賴。如果您使用Maven&#xff0c;可以在pom.xml中添加如下依賴&#xff1a; &l…

【網絡與系統安全】強制訪問控制——BLP模型

一、模型背景與定義 BLP&#xff08;Bell-LaPadula&#xff09;模型是由David Bell和Len Adula在1973年提出的強制訪問控制&#xff08;MAC&#xff09;模型&#xff0c;是最早的計算機安全模型之一&#xff0c;主要用于解決多用戶系統中的信息機密性保護問題&#xff0c;尤其…

HTTPS詳解:原理 + 加解密過程 + 面試問答

一、HTTP 與 HTTPS 的區別 項目HTTPHTTPS全稱HyperText Transfer ProtocolHyperText Transfer Protocol Secure端口80443協議層應用層應用層 TLS&#xff08;安全層&#xff09;加密方式明文傳輸加密傳輸&#xff08;TLS&#xff09;安全性易被劫持、中間人攻擊可加密、防篡改…

Python-GUI-wxPython-控件

1 需求 2 接口 3.* 控件&#xff1a;wx.StaticText import wxclass MainFrame(wx.Frame):def __init__(self, *args, **kwargs):super(MainFrame, self).__init__(*args, **kwargs)self.init_ui()self.Center()self.Maximize()def init_ui(self):static_text wx.StaticText(pa…

3-1 PID算法改進(積分部分)

目錄 1、積分限幅 2、積分分離 3、變速積分 在位置式PID的基礎上進行改進 定速用PI控制&#xff0c;定位置用PD控制 1、積分限幅 在定速控制上體現 第一種方法確定上下限方法&#xff1a;Out最大時&#xff0c;除以Ki&#xff0c;得到一個值&#xff0c;上限不能超過這個…

Linux探秘坊-------13.進程間通信

1.進程間通信?的 2.管道 2.1 匿名管道 -----通常用來實現 父子通信 創建子進程時&#xff0c;需要把父進程的進程內容全部拷貝一份&#xff0c;但文件管理是不需要拷貝的 但是我們把父進程的文件描述符表給拷貝下來了&#xff0c;文件描述符表里是一堆指針&#xff0c;他們仍…

深入理解Vapnik-Chervonenkis(VC)維度:機器學習泛化能力的理論基礎

引言 通過本篇閱讀,從理論上去理解為什么: 要選擇復雜度低的模型 過擬合的時候,增加樣本量有用 以及如何根據樣本量選擇特征個數 PAC機器學習框架, VC 維是機器學習最重要的基礎理論之一 在機器學習領域&#xff0c;模型泛化能力是衡量算法性能的核心指標…

redis持久化-純緩存模式

redis持久化-純緩存模式 文檔 redis單機安裝redis常用的五種數據類型redis數據類型-位圖bitmapredis數據類型-基數統計HyperLogLogredis數據類型-地理空間GEOredis數據類型-流Streamredis數據類型-位域bitfieldredis持久化-RDBredis持久化-AOFredis持久化-RDBAOF混合模式 官…

HTML DOM 訪問

HTML DOM 訪問 引言 HTML DOM&#xff08;文檔對象模型&#xff09;是現代Web開發中不可或缺的一部分。它允許開發者通過JavaScript操作HTML文檔中的元素&#xff0c;從而實現豐富的交互效果。本文將詳細介紹HTML DOM的訪問方法&#xff0c;包括如何獲取元素、如何修改元素屬…

雙系統如何做接口認證-V1

現有A系統&#xff0c;B系統&#xff0c;A系統啟動的時候調用B系統的注冊接口API1&#xff08;把A系統配置信息注冊到B系統&#xff09;&#xff0c;A系統定時向B系統接口AP2發送心跳信息&#xff0c;B系統根據業務情況&#xff0c;調用A系統的業務接口AP3&#xff0c;請設計兩…

Wireshark TS | 詭異的光貓網絡問題

前言 來自于朋友分享的一個案例&#xff0c;最后定位的原因是光貓問題&#xff0c;而類似這類的設備所產生的網絡問題&#xff0c;也曾碰到過兩三次&#xff0c;但這一次的數據包現象挺特別&#xff0c;分析思路和過程也有所不同&#xff0c;故記錄分享一下。 問題背景 用戶所反…

mac mini m4安裝node.js@16以下版本方法

設備&#xff1a;mac mini m4 目的&#xff1a;使用nvm 安裝 node.js14.x 版本 結果&#xff1a;安裝不上 原因&#xff1a;Node.js 14 發布時&#xff0c;Apple Silicon&#xff08;M1/M2&#xff09;尚未普及&#xff0c;因此 沒有官方預編譯的 macOS ARM64 版本 處理方案&am…

系統安全設計方案,軟件系統安全設計方案

1.1 總體設計 1.1.1 設計原則 1.2 物理層安全 1.2.1 機房建設安全 1.2.2 電氣安全特性 1.2.3 設備安全 1.2.4 介質安全措施 1.3 網絡層安全 1.3.1 網絡結構安全 1.3.2 劃分子網絡 1.3.3 異常流量管理 1.3.4 網絡安全審計 1.3.5 網絡訪問控制 1.3.6 完整性檢查 1.…

Python入門Day3

Python的基礎數據類型 1.Python中提供了六種內置的數據類型&#xff0c;一般用于存儲數據&#xff1a; –數值Number –字符串String –列表List –元組Tuple –字典Dictionary –集合Set 2.Python中的數據類型可以做以下幾個分類&#xff1a; –有序&#xff1a;可以使用下標…