可以快速绑定,视频链接地址:

UE4自制开源动画重定向插件_哔哩哔哩_bilibili

# -*- coding: utf-8 -*-
from pyfbsdk import *
from pyfbsdk_additions import *
import xml.etree.ElementTree as ET
import _winreg
from os import walk
import os.path
import os
import glob
import re
#python api https://help.autodesk.com/view/MOBPRO/2019/ENU/?guid=__py_ref_index_html
#获取系统默认路径
def GetWindowsOSDesktopPath():key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders')desktopFilepath = _winreg.QueryValueEx(key, 'Desktop')[0]  return  str(desktopFilepath)class MotionBuilderTool:def __init__(self):self.tool = FBCreateUniqueTool('快速动画重定向插件')self.tool.StartSizeX = 650self.tool.StartSizeY = 650#窗口布局self.PopulateconfigLayout(self.tool)ShowTool(self.tool)#窗口销毁事件回调self.tool.OnUnbind.Add(self.OnToolDestroy)self.LoadConfigHistory()def LoadConfigHistory(self):self.modelFileEdit = 'C:\\Users\\26593\\Desktop\\demo\\SK_Mannequin.FBX'self.skeletonDefinitionTemplateEdit = 'C:\\Users\\26593\\Desktop\\demo\\template.xml'self.TPoseConfigEdit = ''self.animationRepositoryEdit = 'C:\Users\\26593\\Desktop\demo\\animationRepository'self.outputEdit = 'C:\Users\\26593\\Desktop\\demo\\outputEdit'self.MergeEdit = 'C:\\Users\\26593\\Desktop\\demo\\Ying6_Tpos.FBX'#窗口销毁事件回调def OnToolDestroy(self, control, event):FBSystem().Scene.OnChange.Remove(SceneChanged)#窗口布局def PopulateconfigLayout(self, mainLayout):#配置大小区域x = FBAddRegionParam(10, FBAttachType.kFBAttachLeft, '')y = FBAddRegionParam(20, FBAttachType.kFBAttachTop, '')w = FBAddRegionParam(-10, FBAttachType.kFBAttachRight, '')h = FBAddRegionParam(600, FBAttachType.kFBAttachNone, '')mainLayout.AddRegion('Config', '', x, y, w, h)#创建纵向布局configLayout = FBVBoxLayout()mainLayout.SetControl('Config', configLayout)mainLayout.SetBorder('Config', FBBorderStyle.kFBStandardBorder ,True, True,2,2,200,0)#打开路径Button_1 = FBButton()Button_1.Look = FBButtonLook.kFBLookColorChangeButton_1.OnClick.Add(self.OpenModelFile)Button_1.Caption = '打开路径'configLayout.Add(Button_1, 50)#加载模型Button_2 = FBButton()Button_2.Look = FBButtonLook.kFBLookColorChangeButton_2.OnClick.Add(self.LoadModelFile)Button_2.Caption = '加载模型'configLayout.Add(Button_2, 50)#定义骨架Button_3 = FBButton()Button_3.Look = FBButtonLook.kFBLookColorChangeButton_3.OnClick.Add(self.DefineSkeleton)Button_3.Caption = '定义骨架'configLayout.Add(Button_3, 50)#把骨架映射到motion默认的系统上Button_4 = FBButton()Button_4.Look = FBButtonLook.kFBLookColorChangeButton_4.OnClick.Add(self.Characterize)Button_4.Caption = '映射'configLayout.Add(Button_4, 50)"""#跳转到控制面板Button_5 = FBButton()Button_5.Look = FBButtonLook.kFBLookColorChangeButton_5.OnClick.Add(self.PlotToControlRig)Button_5.Caption = '跳转到控制面板'configLayout.Add(Button_5, 50)#加载动画到重定向目标Button_6 = FBButton()Button_6.Look = FBButtonLook.kFBLookColorChangeButton_6.OnClick.Add(self.LoadAnimationForRetargeting)Button_6.Caption = '加载动画到重定向目标'configLayout.Add(Button_6, 50)"""#打开MergeButton_7 = FBButton()Button_7.Look = FBButtonLook.kFBLookColorChangeButton_7.OnClick.Add(self.OpenMerge)Button_7.Caption = '打开Merge'configLayout.Add(Button_7, 50)#选sourceButton_8 = FBButton()Button_8.Look = FBButtonLook.kFBLookColorChangeButton_8.OnClick.Add(self.SetSource)Button_8.Caption = '选Source'configLayout.Add(Button_8, 50)#添加角色动画轨道Button_10 = FBButton()Button_10.Look = FBButtonLook.kFBLookColorChangeButton_10.OnClick.Add(self.AddCharacterAnimationTrack)Button_10.Caption = '添加角色动画轨道'configLayout.Add(Button_10, 50)#烘焙动画到新骨骼Button_9 = FBButton()Button_9.Look = FBButtonLook.kFBLookColorChangeButton_9.OnClick.Add(self.PlotSkeleton)Button_9.Caption = '烘焙动画到新骨骼'configLayout.Add(Button_9, 50)#输出动画Button_11 = FBButton()Button_11.Look = FBButtonLook.kFBLookColorChangeButton_11.OnClick.Add(self.SaveAnimationFile)Button_11.Caption = '输出动画'configLayout.Add(Button_11, 50)#打开模型文件def OpenModelFile(self, contorl, event):# 创建弹出窗口并设置必要的初始值filePopup = pyfbsdk.FBFilePopup()filePopup.Caption = '选择你的原始动画文件'filePopup.Style = pyfbsdk.FBFilePopupStyle.kFBFilePopupOpenfilePopup.Filter = '*.fbx'# 设置默认路径(假设我们使用windows操作系统)filePopup.Path = GetWindowsOSDesktopPath()# 让GUI显示出来bResult = filePopup.Execute()if bResult:self.modelFileEdit = filePopup.FullFilename#打开骨骼定义映射表def OpenSkeletonDefinitionTemplateFile(self, contorl, event):# 创建弹出窗口并设置必要的初始值filePopup = pyfbsdk.FBFilePopup()filePopup.Caption = '选择您的骨骼定义映射表'filePopup.Style = pyfbsdk.FBFilePopupStyle.kFBFilePopupOpenfilePopup.Filter = '*.xml'# 设置默认路径(假设我们使用windows操作系统)filePopup.Path = GetWindowsOSDesktopPath()# 让GUI显示出来bResult = filePopup.Execute()if bResult:self.skeletonDefinitionTemplateEdit= filePopup.FullFilename#打开动画存储文件夹def OpenAimationRepositoryFolder(self, contorl, event):# 创建弹出窗口并设置必要的初始值folderPopup = pyfbsdk.FBFolderPopup()folderPopup.Caption = '选择您的动画存储文件夹'# 设置默认路径(假设我们使用windows操作系统)folderPopup.Path = GetWindowsOSDesktopPath()# 让GUI显示出来result = folderPopup.Execute()if result:self.animationRepositoryEdit = folderPopup.Path#打开输出文件夹def OpenOutputFolder(self, contorl, event):# 创建弹出窗口并设置必要的初始值folderPopup = pyfbsdk.FBFolderPopup()folderPopup.Caption = '选择您的输出文件夹'# 设置默认路径(假设我们使用windows操作系统)folderPopup.Path = GetWindowsOSDesktopPath()# 让GUI显示出来result = folderPopup.Execute()if result:self.outputEdit = folderPopup.Path#加载模型文件def LoadModelFile(self, control, event):   targetFilepath = self.modelFileEditif targetFilepath == '':FBMessageBox( 'Config','没有模型文件路径', 'OK', None, None )returnapp = FBApplication()app.FileNew()loadOption = FBFbxOptions(True)loadOption.NamespaceList = 'UE4'app.FileOpen(targetFilepath, True, loadOption)#定义骨架def DefineSkeleton(self, control, event):skeletonDefinitionTemplateFilepath = self.skeletonDefinitionTemplateEditif skeletonDefinitionTemplateFilepath == '':FBMessageBox( 'Config', '无框架定义模板文件路径.', 'OK', None, None )return# 待办事项:在这里需要验证操作currentCharacter = FBApplication().CurrentCharacter# 如果没有角色,就创造一个if currentCharacter == None:     currentCharacter = FBCharacter('UE4:Character')FBApplication().CurrentCharacter = currentCharactertree = ET.parse(skeletonDefinitionTemplateFilepath)root = tree.getroot()# 待办事项:现在这里没有匹配操作for elem in tree.iter(tag='item'):jointName = 'UE4:'+elem.attrib['value']targetLinkSlotName = elem.attrib['key'] + 'Link'if jointName == '':continuejoint = FBFindModelByLabelName(jointName)if joint == None:print('骨架定义模板中的意外连接: %s' % (jointName))else:property = currentCharacter.PropertyList.Find(targetLinkSlotName)property.removeAll()property.append (joint)#动画文件是否存在def IsAnimationFileValid(self, animationFileFullFilename):# 获取目标网格文件名targetMeshFullFilename = self.modelFileEdittargetMeshBasename = os.path.basename(targetMeshFullFilename)targetMeshName,_ = os.path.splitext(targetMeshBasename)baseName = os.path.basename(animationFileFullFilename)fileNameWithoutExtention,_ = os.path.splitext(baseName)parttern = targetMeshName + r'_Ani_\w+'match = re.search(parttern, fileNameWithoutExtention ) result = not match == Nonereturn  result#在存储库文件夹中找到动画def FindAnimationInRepositoryFolder(self, control, event):self.foundlAnimationFileList.Items.removeAll()animationRepositoryFolder = self.animationRepositoryEditbValidFolderPath = os.path.isdir(animationRepositoryFolder)if not bValidFolderPath:FBMessageBox( 'Config','无效的动画存储库文件夹', 'OK', None, None )returnfoundFbxFiles = glob.glob(animationRepositoryFolder +'/*.fbx')for f in foundFbxFiles:if self.IsAnimationFileValid(f):self.foundlAnimationFileList.Items.append(f)# 如果没有找到动画文件就打印if self.foundlAnimationFileList.Items.len == 0:print('没有发现动画')return#描述-把骨架映射到motion默认的系统上def Characterize(self, control, event):currentCharacter = FBApplication().CurrentCharacterif currentCharacter == None:FBMessageBox( 'Config', '没有定义角色', 'OK', None, None )return # 这里的True指的是两足动物的特征currentCharacter.SetCharacterizeOn(True)FBSystem().Scene.Evaluate()#跳转到控制面板def PlotToControlRig(self, control, event):currentCharacter = FBApplication().CurrentCharacterif currentCharacter == None:FBMessageBox( 'Config', '没有定义角色', 'OK', None, None )return # 禁用并删除控制RigcurrentCharacter.ActiveInput = FalsecontrolRig = currentCharacter.GetCurrentControlSet()# 如果没有控制Rig,就创建一个新的if not controlRig:# 使用“True”参数指定的正运动学和逆运动学创建一个控制RigbCreationResult = currentCharacter.CreateControlRig(True)if not bCreationResult:print('在PlotToControlRig中创建新的控制rig失败,请检查')plotOptions = FBPlotOptions()plotOptions.ConstantKeyReducerKeepOneKey = FalseplotOptions.PlotAllTakes = True plotOptions.PlotOnFrame = TrueplotOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )plotOptions.PlotTranslationOnRootOnly = FalseplotOptions.PreciseTimeDiscontinuities = FalseplotOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnrollplotOptions.UseConstantKeyReducer = FalsecurrentCharacter.PlotAnimation (FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,plotOptions )#加载动画到重定向目标def LoadAnimationForRetargeting(self, control, event):fbxOptions = FBFbxOptions( True )fbxOptions.TransferMethod = FBCharacterLoadAnimationMethod.kFBCharacterLoadRetargetplotOptions = FBPlotOptions()animFile = 'C:\Users\26593\Desktop\demo\Bow_Run_Fwd_45_L.fbx'currentCharacter = FBApplication().CurrentCharacterif currentCharacter == None:FBMessageBox( 'Config', '没有定义角色', 'OK', None, None )return FBApplication().LoadAnimationOnCharacter( animFile, currentCharacter, fbxOptions, plotOptions )#执行测试def ExecuteTest(self, control, event): # 首先,清除场景并打开目标网格文件# 从框架模板定义# 描述# 控制Rig# 指定动画文件# 加载动画self.FindAnimationInRepositoryFolder() #打开Mergedef OpenMerge(self, control, event): # 文件路径nativeFile = self.MergeEditoptions = FBFbxOptions(True, nativeFile)options.SetAll(FBElementAction.kFBElementActionMerge, True)for takeIndex in range( 0, options.GetTakeCount() ):# 取消选择optionsoptions.SetTakeSelect( takeIndex, True )FBApplication().FileMerge( nativeFile, False, options )#选sourcedef SetSource(self, control, event): # 选characterfoundComponents = FBComponentList()# 选characterFBFindObjectsByName('Character', foundComponents, True, False)Character = foundComponents[0]Character.Selected = True# 选sourcefoundComponents = FBComponentList()FBFindObjectsByName('UE4:Character', foundComponents, True, False)OldCharacter = foundComponents[0]Character.InputCharacter = OldCharacterCharacter.InputType = FBCharacterInputType.kFBCharacterInputCharacterCharacter.ActiveInput = True#烘焙动画到新骨骼def PlotSkeleton(self, control, event): myPlotOptions = FBPlotOptions ()myPlotOptions.ConstantKeyReducerKeepOneKey = FalsemyPlotOptions.PlotAllTakes = FalsemyPlotOptions.PlotOnFrame = TruemyPlotOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )myPlotOptions.PlotTranslationOnRootOnly = FalsemyPlotOptions.PreciseTimeDiscontinuities = FalsemyPlotOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterNonemyPlotOptions.UseConstantKeyReducer = FalseTheChar = FBApplication().CurrentCharacterif TheChar.ActiveInput == True:TheChar.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, myPlotOptions)else:TheChar.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, myPlotOptions)#添加角色动画轨道def AddCharacterAnimationTrack(self, control, event): lParentTrack = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter)#把当前角色赋予轨道foundComponents = FBComponentList()FBFindObjectsByName('UE4:Character', foundComponents, True, False)Character = foundComponents[0]lParentTrack.Details.append(Character)#保存当前动画文件def SaveAnimationFile(self, control, event): # 创建所有的类实例lSystem = FBSystem()lApp = FBApplication()lScene = lSystem.Scene#开始保存当前动画lOptions = FBFbxOptions(False)## 保存选项lOptions.SaveCharacter = FalselOptions.SaveControlSet = TruelOptions.SaveCharacterExtension = Falseif len( lScene.Characters ) > 0:lApp.SaveCharacterRigAndAnimation(self.animationRepositoryEdit + '\\Ying6_Bow_Run_Fwd_45_L.fbx', lScene.Characters[0], lOptions)MotionBuilderTool()

MotionBuilder自制插件相关推荐

  1. chrome自制插件--百度搜索结果去广告1.0

    chrome自制插件--百度搜索结果去广告1.0 一.前言 二.效果 三.说明 四.安装 五.下载 一.前言 国内用户用百度的占绝大多数,但是百度搜索结果的广告真烦人,特别是搜索"黄金&qu ...

  2. chrome自制插件--动易网站后台一键登录v1.4

    动易网站后台一键登录v1.4 一.介绍 二.功能 三.安装 四.使用 五.GitHub源码 一.介绍 上篇<chrome自制插件–简单一键登录(附插件开发介绍)>我介绍了chrome插件开 ...

  3. MotionVenus·MotionBuilder实时插件

                                                                MotionVenus·MotionBuilder实时插件 1.1 简介 (1) ...

  4. chrome自制插件--简单一键登录(附插件开发介绍)

    chrome自制插件--简单一键登录(附插件开发介绍) 一.前言 二.需求 三.文件结构及代码 3.1 第一步:建立文件 3.2 第二步:修改manifest.json,配置插件 3.3 第三步:修改 ...

  5. 【自制插件】B站专栏语音朗读器 v1.0 专栏你太美

    这两天下班没事的时候,稍微自制了个简单的B站专栏朗读器插件.什么样的呢? 就这样!2333333333333. (渣渣前端程序员一枚,高科技啥的就不会搞了,只会写点小东西维持生活这样子) (然而该插件 ...

  6. 【自制插件】将MMD4Mecanim转换的MMD模型导入maya

    这个已经废弃了_(:зゝ∠)_,另外做了升级版: http://www.cnblogs.com/marisa/p/5174150.html ============================== ...

  7. sql server 怎么把视图中的数据存到另外一张表中_承上篇,自制插件优化Kep数据存储问题...

    序言:上篇说到Kep数据日志存储是将所有数据存到一张表内,不好筛选,为此抽空做了这个插件对Kep存到SQL的数据表进行优化处理. 一.插件安装及界面功能标注 1.双击安装包弹出安装向导,直接下一步直到 ...

  8. idea如何自制插件_Lice IntelliJ插件图标制作过程

    这是只属于没有Photoshop的人的悲哀. 首先先大吼一声--劳资终于做出了高清无码的Lice图标! 直接进入正题 其实我还是想说一下事情的发展过程的-- 我想照着IntelliJ IDEA的图标风 ...

  9. idea如何自制插件_Minecraft插件开发教程-开发环境配置 [原创]

    Hello 各位小阔爱们好 时隔2个多月 我又回来了 这一期专栏有些特别 让我们一起来制作一个简单的Minecraft插件吧~ 本教程为原创作品 不得随意转载 求硬币 收藏 点赞 关注! 写专栏是贞德 ...

最新文章

  1. asp.net的定义
  2. 编写python程序输出图形_python 图形化编程---文本输入框
  3. python urllib.request 爬虫 数据处理-使用Python3.5写简单网络爬虫
  4. python学习-序列化对象(pickle)
  5. 《深入理解Java虚拟机》读书笔记八
  6. java中怎样上传zip_java服务器如何对zip文件分包上传?
  7. unity 2d文字跟随主角移动_时间回溯——用Unity实现时空幻境(Braid)中的控制时间效果...
  8. 汽车诊断协议UDS概述
  9. linux dstat,dstat 用法详解
  10. 正切函数半角定理推导
  11. matlab读取nc\hdf\grd等气象文件 自用
  12. 机器视觉(四)——打光
  13. 2019.11.2图论专题(AtCoder Splatter Painting、President and Roads、Shortest Cycle、ISlands II)
  14. 创新创意springboot计算机毕业设计题目300例,总有你需要用到的!
  15. 全开源办公开发平台——手机移动端APP功能简介
  16. ApacheCN 翻译活动进度公告 2019.4.15
  17. sqlyog修改背景颜色成护眼色
  18. 【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 新发出品 良心教程)
  19. Windows 8.1 归档 —— Step 3 软件的选择与安装
  20. 彻底解决让用户清一下浏览器缓存

热门文章

  1. 很高兴,今天开了博客
  2. thinkphp开发app商城项目源码下载(thinkphp)
  3. 为什么拼团电商APP能成功?
  4. ClickHouse 在网易的实践
  5. 赋予角色生命的游戏配音技巧
  6. TypeScript(七)泛型、声明合并、扩展阅读
  7. 汽车方向盘电子助力转向器如何接线_相比于液压助力,电子助力有什么优势?...
  8. 微生物组-宏基因组分析专题研讨会(2022.4,线下)
  9. 西门子S7-300控制PVC配料注塑机程序 称重仪表通讯,模拟量控制
  10. Matnote_2_数据的同质性 Data Homogeneity