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 Optional

import maya.cmds as mc

space_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 = obj
        self.__parent = parent

    @property
    def parent(self):
        """Returns the parent of the object"""
        return self.__parent

    def __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 Dialog

    This 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 related
        self._textfield = ""
        self._scale_field = ""
        self._frame_field = ""
        self._rotation_order = ""
        self._reload = ""

        # Other
        self._root_node = None  # Used for targeting

        # BVH specific stuff
        self._filename = ""
        self._channels = []

        self.setup_ui()

    def setup_ui(self):
        """
        Builds the UI
        """
        win = self._name
        if mc.window(win, ex=True):
            mc.deleteUI(win)

        # Non sizeable dialog
        win = 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 UI
        mc.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)

        # Footer
        mc.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):
            return

        self._filename = result[0]

        mc.button(self._reload, e=True, enable=True)

        # Action!
        self._read_bvh()

    def load_bvh(self, filename):
        self._filename = filename
        self._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 appending
        self._channels = []

        # Scale the entire rig and animation
        rig_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) - 1

        with 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 False

            if 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 spaces
                if not motion:
                    # root joint
                    if line.startswith("ROOT"):
                        # Set the Hip joint as root
                        if 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_parent
                            mc.textField(self._textfield,
                                         e=True,
                                         text=my_parent.full_path())

                    if "JOINT" in line:
                        jnt = space_re.split(line.strip())
                        # Create the joint
                        my_parent = TinyDAG(jnt[1], my_parent)

                    if "End Site" in line:
                        # Finish up a hierarchy and ignore a closing bracket
                        safe_close = True

                    if "}" in line:
                        # Ignore when safeClose is on
                        if safe_close:
                            safe_close = False
                            continue

                        # Go up one level
                        if my_parent is not None:
                            my_parent = my_parent.parent
                            if 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 animated
                        for 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 exists
                        if mc.objExists(my_parent.full_path()):
                            jnt = my_parent.full_path()
                        else:
                            # Build a new joint
                            jnt = 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 = True

                else:
                    # 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 channels
                        for index, value in enumerate(data):
                            mc.setKeyframe(self._channels[index],
                                           time=frame,
                                           value=float(value))

                        frame = frame + 1

    def _clear_animation(self):
        if self._root_node is None:
            mc.error("Could not find root node to clear animation.")
            return

        # Select hierarchy
        mc.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 connections
                connections = mc.listConnections("%s.%s" % (node, attr),
                                                 s=True,
                                                 d=False)
                if connections is not None:
                    mc.delete(connections)

            for attr in rot_attrs:
                # Reset rotation
                mc.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 = None
            mc.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 math

import maya.cmds as cmds
import maya.api.OpenMaya as om


def 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 rotation


def 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_str


def export_hierarchy(joints, rot_order: str):
    hierarchy_str = "HIERARCHY\n"

    def _process_joint(joint, indent):
        nonlocal hierarchy_str
        joint_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_str


def 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 + 1
    frame_rate = cmds.playbackOptions(query=True, framesPerSecond=True)
    if frame_rate == 0:
        frame_rate = 24.0
    frame_time = 1.0 / frame_rate

    with 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_joints


if __name__ == "__main__":
    root_joint_name = "root"
    root_joint = None
    children = 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 path
    output_file_path = os.path.join(
        os.path.expanduser("~"), "maya_body_test.bvh")

    export_bvh(joints, output_file_path, start_frame, end_frame, "ZYX")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/483600.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OD C卷 - 反射计数

反射计数(200) 给定一个包含0 、1的二维矩阵;一个物体从给定的初始位置出发,在给定的速度下移动,遇到矩阵的边缘则发生镜面反射,无论物体经过0还是1,都不影响其速度;经过t时间单位后…

学习次模函数-第2章 定义

纵观本专著,我们认为及其幂集(即, 所有子集的集合),其基数为。我们也考虑一个实值集函数,使得。 与凸函数的一般约定相反(见附录A),我们不允许函数有无穷大的值。 次模分…

文件包含一-WEB攻防-PHP应用文件包含LFIRFI伪协议编码算法无文件利用黑白盒

演示案例: 文件包含-原理&分类&利用&修复黑盒利用-VULWEB-有无包含文件白盒利用-CTFSHOW-伪协议玩法 #文件包含-原理&分类&利用&修复 1、原理 程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时&#xff0c…

基于物理的实时渲染 -- PBR

简介 PBR,或者用更通俗一些的称呼是指基于物理的渲染(Physically Based Rendering),它指的是一些在不同程度上都基于与现实世界的物理原理更相符的基本理论所构成的渲染技术的集合。正因为基于物理的渲染目的便是为了使用一种更符合物理学规律的方式来模…

面试题(二)

目录 21.JVM中哪些是线程共享区 22.你们项⽬如何排查JVM问题 23.⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程? 24.怎么确定⼀个对象到底是不是垃圾? 25.GC Root 是什么? 26.JVM有哪些垃圾回收算法? 27.…

RabbitMQ 01

01.定义 02.功能

18个西语常用前置词用法大全,柯桥西班牙语培训

西语词类有九种:名词、冠词、形容词、代词、动词、副词、感叹词、前置词和连接词。 其中,“前置词”也就是我们俗称的“介词”,它是一种不变词类,本身没有独立的词汇意义,在句中与名词、形容词、动词等连用&#xff0…

BM43 包含min函数的栈(Stack)

import java.util.*; import java.util.Stack;public class Solution {Stack<Integer> s1 new Stack<Integer>();//存最小的元素Stack<Integer> s2 new Stack<Integer>();public void push(int node) {s1.push(node);if(s2.isEmpty() || s2.peek() &…

2024-03-23 问AI: 介绍一下深度学习中的ReLU函数

文心一言 ReLU&#xff08;Rectified Linear Unit&#xff09;函数是深度学习领域中常用的一种激活函数。它具有简单、计算高效且在某些情况下能有效缓解梯度消失问题等优点&#xff0c;因此在神经网络中得到了广泛的应用。 ReLU函数的定义非常简单&#xff0c;其数学表达式为…

Element Plus 基本使用

一、概述 1.1介绍 Element Plus 基本使用 element-ui 是基于vue 开发的一套ui组件库&#xff0c;提供丰富的网页开发组件&#xff0c;可用快速开发网站&#xff0c;降低前端开发成本版本 element目前有两个版本 element-ui&#xff1a;基于vue2element-plus: 基于vue3 官网地址…

2-dubbo源码 : 源码环境搭建

好的开始是成功的一半&#xff0c;阅读源码也是一样。 很多同学在下定决心阅读一个开源框架之后&#xff0c;就一头扎进去&#xff0c;迷失在代码“迷宫”中。此时&#xff0c;有同学意识到&#xff0c;需要一边 Debug 一边看&#xff1b;然后又有一批同学在搭建源码环境的时候…

鸿蒙一次开发,多端部署(十五)常见问题

如何查询设备类型 设备类型分为default&#xff08;默认设备&#xff09;、tablet、tv、wearable、2in1等&#xff0c;有多种查询设备类型的方式。 通过命令行的方式查询设备类型。 通过命令行查询指定系统参数&#xff08;const.product.devicetype&#xff09;进而确定设备…

Java基础-常用类

文章目录 1.Math类2.System类1.exit代码 结果2.arraycopy参数解释代码结果 3.currentTimeMillens代码结果 3.大数处理方案基本介绍BigInteger类介绍代码结果 BigDecimal类介绍代码结果 4.日期类对于IDEA类图中的属性![image-20240101190844530](https://img-blog.csdnimg.cn/im…

能降低嵌入式系统功耗的三个技术

为电池寿命设计嵌入式系统已经成为许多团队重要的设计考虑因素。优化电池寿命的能力有助于降低现场维护成本&#xff0c;并确保客户不需要不断更换或充电电池&#xff0c;从而获得良好的产品体验。 团队通常使用一些标准技术来提高电池寿命&#xff0c;例如将处理器置于低功耗…

RIPGeo代码理解(六)main.py(运行模型进行训练和测试)

​代码链接:RIPGeo代码实现 ├── preprocess.py # 预处理数据集并为模型运行执行IP聚类 ├── main.py # 运行模型进行训练和测试 ├── test.py #加载检查点,然后测试 一、导入各种模块和数据库 import torch.nnfrom lib.utils import * import argparse i…

162、应急响应——网站入侵篡改指南Webshell内存马查杀漏洞排查时间分析

文章目录 IIS&.NET—注入—基于时间配合日志分析Apache&PHP—漏洞—基于漏洞配合日志分析Tomcat&JSP—弱口令—基于后门配合日志分析查杀常规后门查杀内存马 需要了解&#xff1a; 异常检测、处置流程、分析报告等 网站被入侵会出现异常&#xff1a;流量异常、防护…

Git版本控制

这是两个学习Git推荐必看的文档&#xff0c;第一个链接是Git的官方权威文档&#xff0c;第二个链接是国内程序员在开发中&#xff0c;总结的Git快速入门教程&#xff0c;掌握这个&#xff0c;也足够应付在工作中的场景。 Git权威书籍《ProGit》中文版https://gitee.com/progit…

Web框架开发-Ajax

一、 Ajax准备知识:json 1、json(Javascript Obiect Notation,JS对象标记)是一种轻量级的数据交换格式 1 2 它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。…

从redis安装到使用再到源码和底层原理分析指南【万字长文】

Redis 安装redis-cli记录单线程多路IO复用Redis字符串Redis列表 事务Redis悲观锁和乐观锁AOF主从集群概念slots Redis应用问题解决缓存穿透缓存击穿缓存雪崩分布式锁 重启和停止redis server配置登陆密码 配置外网访问Redis源码学习server守护进程实现server处理信号redis obje…

每日一题——LeetCode2549.统计桌面上的不同数字

方法一 模拟 维护一个数组arr&#xff0c;初始值为n,每次循环将arr[i] % j(1<j<n) 如果结果为1则将j加入&#xff0c; 最后将arr转为Set集合去重&#xff0c;Set的长度就是答案 var distinctIntegers function(n) {let arr[]arr.push(n)for(let i0;i<arr.length;i…