maya打开bvh脚本
目录
maya打开脚本编辑器
运行打开bvh脚本
maya导出bvh脚本
maya打开脚本编辑器
打开Maya软件,点击右下角 “脚本编辑器”
运行打开bvh脚本
https://github.com/jhoolmans/mayaImporterBVH/blob/master/bvh_importer.py
import os
import re
from typing import Optionalimport maya.cmds as mcspace_re = re.compile(r"\s+")# This maps the BVH naming convention to Maya
translationDict = {"Xposition": "translateX","Yposition": "translateY","Zposition": "translateZ","Xrotation": "rotateX","Yrotation": "rotateY","Zrotation": "rotateZ"
}class TinyDAG(object):"""Tiny DAG class for storing the hierarchy of the BVH file."""def __init__(self, obj: str, parent: Optional["TinyDAG"] = None):"""Constructor"""self.obj = objself.__parent = parent@propertydef parent(self):"""Returns the parent of the object"""return self.__parentdef __str__(self) -> str:"""String representation of the object"""return str(self.obj)def full_path(self) -> str:"""Returns the full path of the object"""if self.parent is not None:return "%s|%s" % (self.parent.full_path(), str(self))return str(self.obj)class BVHImporterDialog(object):"""BVH Importer DialogThis class is the main dialog for the BVH importer."""def __init__(self, debug=False):self._name = "bvhImportDialog"self._title = "BVH Importer v2.0"if debug:print("Debug is deprecated.")# UI relatedself._textfield = ""self._scale_field = ""self._frame_field = ""self._rotation_order = ""self._reload = ""# Otherself._root_node = None # Used for targeting# BVH specific stuffself._filename = ""self._channels = []self.setup_ui()def setup_ui(self):"""Builds the UI"""win = self._nameif mc.window(win, ex=True):mc.deleteUI(win)# Non sizeable dialogwin = mc.window(self._name, title=self._title, w=200, rtf=True,sizeable=False)mc.columnLayout(adj=1, rs=5)mc.separator()mc.text("Options")mc.separator()mc.rowColumnLayout(numberOfColumns=2,columnWidth=[(1, 80), (2, 150)],cal=[(1, "right"), (2, "center")],cs=[(1, 5), (2, 5)],rs=[(1, 5), (2, 5)])mc.text("Rig scale")self._scale_field = mc.floatField(minValue=0.01, maxValue=2, value=1)mc.text("Frame offset")self._frame_field = mc.intField(minValue=0)mc.text("Rotation Order")self._rotation_order = mc.optionMenu()mc.menuItem(label='XYZ')mc.menuItem(label='YZX')mc.menuItem(label='ZXY')mc.menuItem(label='XZY')mc.menuItem(label='YXZ')mc.menuItem(label='ZYX')mc.setParent("..")mc.separator()# Targeting UImc.text("Skeleton Targeting")mc.text("(Select the hips)")mc.separator()mc.rowColumnLayout(numberOfColumns=2,columnWidth=[(1, 150), (2, 80)],cs=[(1, 5), (2, 5)],rs=[(1, 5), (2, 5)])self._textfield = mc.textField(editable=False)mc.button("Select/Clear", c=self._on_select_root)mc.setParent("..")mc.separator()mc.button("Import..", c=self._on_select_file)self._reload = mc.button("Reload", enable=False, c=self._read_bvh)# Footermc.text("by Jeroen Hoolmans")mc.window(win, e=True, rtf=True, sizeable=False)mc.showWindow(win)def _on_select_file(self, e):"""Callback for the import button."""file_filter = "All Files (*.*);;Motion Capture (*.bvh)"result = mc.fileDialog2(fileFilter=file_filter, dialogStyle=1, fm=1)if result is None or not len(result):returnself._filename = result[0]mc.button(self._reload, e=True, enable=True)# Action!self._read_bvh()def load_bvh(self, filename):self._filename = filenameself._read_bvh()def _read_bvh(self, *_args):# Safe close is needed for End Site part to keep from setting new# parent.safe_close = False# Once motion is active, animate.motion = False# Clear channels before appendingself._channels = []# Scale the entire rig and animationrig_scale = mc.floatField(self._scale_field, q=True, value=True)frame = mc.intField(self._frame_field, q=True, value=True)rot_order = mc.optionMenu(self._rotation_order, q=True, select=True) - 1with open(self._filename) as f:# Check to see if the file is valid (sort of)if not f.readline().startswith("HIERARCHY"):mc.error("No valid .bvh file selected.")return Falseif self._root_node is None:# Create a group for the rig, easier to scale.# (Freeze transform when ungrouping please..)mocap_name = os.path.basename(self._filename)grp = mc.group(em=True, name="_mocap_%s_grp" % mocap_name)mc.setAttr("%s.scale" % grp, rig_scale, rig_scale, rig_scale)# The group is now the 'root'my_parent = TinyDAG(grp, None)else:my_parent = TinyDAG(self._root_node, None)self._clear_animation()for line in f:line = line.replace(" ", " ") # force spacesif not motion:# root jointif line.startswith("ROOT"):# Set the Hip joint as rootif self._root_node:my_parent = TinyDAG(str(self._root_node), None)else:my_parent = TinyDAG(line[5:].rstrip(), my_parent)# Update root node in case we want to reload.self._root_node = my_parentmc.textField(self._textfield,e=True,text=my_parent.full_path())if "JOINT" in line:jnt = space_re.split(line.strip())# Create the jointmy_parent = TinyDAG(jnt[1], my_parent)if "End Site" in line:# Finish up a hierarchy and ignore a closing bracketsafe_close = Trueif "}" in line:# Ignore when safeClose is onif safe_close:safe_close = Falsecontinue# Go up one levelif my_parent is not None:my_parent = my_parent.parentif my_parent is not None:mc.select(my_parent.full_path())if "CHANNELS" in line:chan = line.strip()chan = space_re.split(chan)# Append the channels that are animatedfor i in range(int(chan[1])):self._channels.append("%s.%s" % (my_parent.full_path(),translationDict[chan[2 + i]]))if "OFFSET" in line:offset = line.strip()offset = space_re.split(offset)jnt_name = str(my_parent)# When End Site is reached, name it "_tip"if safe_close:jnt_name += "_tip"# skip if existsif mc.objExists(my_parent.full_path()):jnt = my_parent.full_path()else:# Build a new jointjnt = mc.joint(name=jnt_name, p=(0, 0, 0))mc.setAttr(jnt + ".rotateOrder", rot_order)mc.setAttr(jnt + ".translate",float(offset[1]),float(offset[2]),float(offset[3]))if "MOTION" in line:# Animate!motion = Trueelse:# We don't really need to use Frame count and time# (since Python handles file reads nicely)if "Frame" not in line:data = space_re.split(line.strip())# Set the values to channelsfor index, value in enumerate(data):mc.setKeyframe(self._channels[index],time=frame,value=float(value))frame = frame + 1def _clear_animation(self):if self._root_node is None:mc.error("Could not find root node to clear animation.")return# Select hierarchymc.select(str(self._root_node), hi=True)nodes = mc.ls(sl=True)trans_attrs = ["translateX", "translateY", "translateZ"]rot_attrs = ["rotateX", "rotateY", "rotateZ"]for node in nodes:for attr in trans_attrs + rot_attrs:# Delete input connectionsconnections = mc.listConnections("%s.%s" % (node, attr),s=True,d=False)if connections is not None:mc.delete(connections)for attr in rot_attrs:# Reset rotationmc.setAttr("%s.%s" % (node, attr), 0)def _on_select_root(self, *_args):# When targeting, set the root joint (Hips)selection = mc.ls(sl=True, type="joint", l=True)if len(selection) == 0:self._root_node = Nonemc.textField(self._textfield, e=True, text="")else:self._root_node = selection[0]mc.textField(self._textfield, e=True, text=self._root_node)if __name__ == "__main__":dialog = BVHImporterDialog()
maya导出bvh脚本
https://github.com/zhaozigu/maya-export-bvh/blob/main/export_bvh.py
import os
import mathimport maya.cmds as cmds
import maya.api.OpenMaya as omdef get_bone_rotation(bone):cur_mat = om.MMatrix(cmds.xform(bone, q=True, ws=True, m=True))parent = cmds.listRelatives(bone, p=True)[0]parent_mat = om.MMatrix(cmds.xform(parent, q=True, ws=True, m=True))local_mat = cur_mat * parent_mat.inverse()cur_xfo_mat = om.MTransformationMatrix(local_mat)rotation = [math.degrees(x) for x in cur_xfo_mat.rotation().asVector()]return rotationdef export_motion(joints, start_frame, end_frame, rot_order: tuple):motion_str = ""root_joint = joints[0]for frame in range(start_frame, end_frame + 1):cmds.currentTime(frame)for joint in joints:joint_name = cmds.ls(joint, long=True)[0]rot = get_bone_rotation(joint_name)if joint == root_joint:loc = cmds.xform(joint_name, q=True, translation=True)motion_str += "%.6f %.6f %.6f " % (loc[0], loc[1], loc[2])motion_str += "%.6f %.6f %.6f " % (rot[rot_order[0]], rot[rot_order[1]], rot[rot_order[2]])motion_str += "\n"return motion_strdef export_hierarchy(joints, rot_order: str):hierarchy_str = "HIERARCHY\n"def _process_joint(joint, indent):nonlocal hierarchy_strjoint_name_raw = cmds.ls(joint, long=True)[0]joint_name = joint_name_raw.split("|")[-1].split(":")[-1]if indent == 0:hierarchy_str += "{}ROOT {}\n".format('\t' * indent, joint_name)else:hierarchy_str += "{}JOINT {}\n".format('\t' * indent, joint_name)loc = cmds.xform(joint_name_raw, q=True, translation=True)hierarchy_str += "{}{{\n".format('\t' * indent)hierarchy_str += "{}OFFSET {:.6f} {:.6f} {:.6f}\n".format('\t' * (indent + 1), loc[0], loc[1], loc[2])if indent == 0:hierarchy_str += "{}CHANNELS 6 Xposition Yposition Zposition {}rotation {}rotation {}rotation\n".format('\t' * (indent + 1), rot_order[0], rot_order[1], rot_order[2])else:hierarchy_str += "{}CHANNELS 3 {}rotation {}rotation {}rotation\n".format('\t' * (indent + 1), rot_order[0], rot_order[1], rot_order[2])children = cmds.listRelatives(joint, children=True, type="joint")if children:for child in children:_process_joint(child, indent + 1)else:hierarchy_str += "{}End Site\n".format('\t' * (indent + 1))hierarchy_str += "{}{{\n".format('\t' * (indent + 1))hierarchy_str += "{}OFFSET 0.0 0.0 0.0\n".format('\t' * (indent + 2))hierarchy_str += "{}}}\n".format('\t' * (indent + 1))hierarchy_str += "{}}}\n".format('\t' * indent)root_joint = joints[0]_process_joint(root_joint, 0)return hierarchy_strdef export_bvh(joints, output_file_path, start_frame, end_frame, rot_order="ZXY"):_order = {"XYZ": (0, 1, 2),"XZY": (0, 2, 1),"YXZ": (1, 0, 2),"YZX": (1, 2, 0),"ZXY": (2, 0, 1),"ZYX": (2, 1, 0),}assert rot_order in _order, "The parameters of the rotation order are incorrect"hierarchy = export_hierarchy(joints, rot_order)motion = export_motion(joints, start_frame, end_frame, _order[rot_order])num_frames = end_frame - start_frame + 1frame_rate = cmds.playbackOptions(query=True, framesPerSecond=True)if frame_rate == 0:frame_rate = 24.0frame_time = 1.0 / frame_ratewith open(output_file_path, "w") as output_file:output_file.write(hierarchy)output_file.write(f"MOTION\nFrames: {num_frames}\nFrame Time: {frame_time:.6f}\n")output_file.write(motion)def get_ordered_joints(joint):ordered_joints = [joint]children = cmds.listRelatives(joint, children=True, type="joint")if children:for child in children:ordered_joints.extend(get_ordered_joints(child))return ordered_jointsif __name__ == "__main__":root_joint_name = "root"root_joint = Nonechildren = cmds.listRelatives(root_joint_name, children=True, type="joint")if children:root_joint = children[0]else:raise ValueError(f"No joint found under {root_joint_name}")joints = get_ordered_joints(root_joint)print(joints)start_frame = int(cmds.playbackOptions(query=True, minTime=True))end_frame = int(cmds.playbackOptions(query=True, maxTime=True))# Set the output file pathoutput_file_path = os.path.join(os.path.expanduser("~"), "maya_body_test.bvh")export_bvh(joints, output_file_path, start_frame, end_frame, "ZYX")
相关文章:

maya打开bvh脚本
目录 maya打开脚本编辑器 运行打开bvh脚本 maya导出bvh脚本 maya打开脚本编辑器 打开Maya软件,点击右下角 “脚本编辑器” 运行打开bvh脚本 https://github.com/jhoolmans/mayaImporterBVH/blob/master/bvh_importer.py import os import re from typing impo…...

【JavaSE】数据类型和运算符
前言 从这一篇我们开始Java的学习~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 Java第一个程序 字面常量 字面常量的分类 结合代码理解 类型转换 类型提升 byte与byte的运算 正确写法 字符串类型St…...
Docker 哲学 - ip 的组成规则 与 网关介绍
在 IP 地址中,我们通常将 IP 地址分为两部分:网络部分和主机部分。网络部分用于标识网络,主机部分用于标识该网络中的特定主机。 IP 地址的每个部分(也被称为一个八位组或一个字节)可以是从0到255的任何值。 一个 IPv4…...

数学建模竞赛真的是模型解题一般,但是论文出彩而获奖的吗?
最近,数乐君发现有同学会有这样的问题:在数学建模国赛中,会因为参赛团队的模型解题一般,但论文写得非常精彩而获奖吗? 是的,确实会存在这样的情况。 我们都知道数学建模竞赛最终都是以提交成品论文的形式…...
深度学习常见的三种模型
深度学习模型实际上是一个包含多个隐藏层的神经网络,目前主要有卷积神经网络(CNN)、深度置信网络(DBN)、循环神经网络(RNN)。 1) 卷积神经网络 在机器学习领域,卷积神经网络属于前…...
接口自动化测试分层设计与实践总结
🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号:互联网杂货铺,回复1 ,免费获取软件测试全套资料,资料在手,涨薪更快 接口测试三要素: 参数构造 发起请求&#x…...

集合(下)Map集合的使用
文章目录 前言一、Map接口二、Map接口的实现类 1.HashMap类2.TreeMap类总结 前言 Map集合没有继承Collection接口,不能像List集合和Set集合那样直接使用Collection接口的方法。Map集合其自身通过以key到value的映射关系实现的集合,也有相应的许多方法。类…...
AAPT: error: resource android:attr/dialogCornerRadius not found.
ERROR:D:\android.gradle\caches\transforms-3\b3b98118f65da38d0ad9da84cfc70a72\transformed\appcompat-1.0.0\res\values-v28\values-v28.xml:5:5-8:13: AAPT: error: resource android:attr/dialogCornerRadius not found. 请帮我看看这个错误是什么意思。我改如何做。 这个…...

数字功放VS模拟功放,选择适合你的音频解决方案
数字功放和模拟功放是音频系统中常用的两种功放技术,适用于不同的音频应用,都具有各自的优势和特点。本文将为您详细介绍数字功放和模拟功放的差异,并帮助您找到适合自己的音频解决方案。 1、数字功放是一种利用数字信号处理技术的功放。它将…...
5.88 BCC工具之tcpsynbl.py解读
一,工具简介 tcpsynbl工具以直方图的形式显示SYN到达时的TCP SYN积压大小。这可以让我们了解应用程序距离达到积压限制并丢弃SYN(导致SYN重传产生性能问题)还有多远。 TCP SYN 数据包则通常用于启动 TCP 三次握手过程的第一次握手。 二,代码示例 #!/usr/bin/env python…...

GVRP实现vlan的自动创建和注册
拓扑图 资源已上传 流程 第一、每台交换机的全局及端口下使能GVRP功能 第二、配置交换机的二层连通性,交换机某些端口配置Trunk端口,并允许相应的vlan通过 第三、在交换机4和5配置静态vlan100,然后查看1和3交换机是否有vlan100的定义&…...

Oracle VM VirtualBox修改磁盘大小
一、 修改虚拟机磁盘大小 先把虚拟机停掉。再增加磁盘大小。 路径中有空格的用""包起来。 D:\Program Files\Oracle\VirtualBox>VBoxManage.exe modifyhd "D:\Program Files\VirtualBox VMs\mycentos\mycentos.vdi" --resize 30000 0%...10%...20%...3…...

【嵌入式硬件】步进电机
1.步进电机简介 1.1步进电机基本原理 步进电机的英文是stepping motor。step的中文意思是行走、迈步。所以仅从字面上我们就可以得知,步进电机就是一步一步移动的电动机。说的官方一点儿,步进电机是一种将电脉冲信号转换成相应角位移或者线位移的电动机(直线电机)。下图为…...

FlyControls 是 THREE.js 中用于实现飞行控制的类,它用于控制摄像机在三维空间中的飞行。
demo演示地址 FlyControls 是 THREE.js 中用于实现飞行控制的类,它用于控制摄像机在三维空间中的飞行。 入参: object:摄像机对象,即要控制的摄像机。domElement:用于接收用户输入事件的 HTML 元素,通常…...

【Java程序设计】【C00366】基于(JavaWeb)Springboot的纹理生产图片系统(有论文)
TOC 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,博客中有上百套程序可供参考,欢迎共同交流学习。 项目简介 项目获取 🍅文末点击卡片…...
编译原理Lab. 1 初代编译器实验说明和要求
目录 Lab. 1 初代编译器实验说明和要求一、初代编译器功能描述二、初代编译器文法要求三、初代编译器测试样例四、初代编译器提交要求五、初代编译器实验测试框架说明 代码与思路 Lab. 1 初代编译器实验说明和要求 一、初代编译器功能描述 初代编译器将 C 语言顺序语句序列翻…...
python判断工作日,节假日
一、概述 需要判断一个日期是否为工作日,节假日。 找到一个现成的插件,蛮好用的。 插件介绍 https://pypi.org/project/chinesecalendar/ 判断某年某月某一天是不是工作日/节假日。 支持 2004年 至 2020年,包括 2020年 的春节延长。 兼容…...

练习4-权重衰减(李沐函数简要解析)
环境:练习1的环境 代码详解 0.导入库 import torch from torch import nn from d2l import torch as d2l1.初始化数据 这里初始化出train_iter test_iter 可以查一下之前的获取Fashion数据集后的数据格式与此对应 n_train, n_test, num_inputs, batch_size 20, 100, 200, …...
websocket 中 request-line 中的URI编码问题
首先,request-line组成如下: Request-Line Method SP Request-URI SP HTTP-Version CRLF 在 rfc6455 规范的 5.1.2 Request-URI 中,有这样的描述: The Request-URI is transmitted in the format specified in section 3.2.1. …...

为何ChatGPT日耗电超50万度?
看新闻说,ChatGPT每天的耗电量是50万度,国内每个家庭日均的耗电量不到10度,ChatGPT耗电相当于国内5万个家庭用量。 网上流传,英伟达创始人黄仁勋说:“AI的尽头是光伏和储能”,大佬的眼光就是毒辣ÿ…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...