当前位置: 首页 > news >正文

[小脚本] maya 命令行常用操作

其实这些代码大部分是从 chatgpt 中生成的。

骨骼命名

import maya.cmds as cmdsdef rename_bones():selected_bones = cmds.ls(type="joint")  # 获取选中的骨骼for bone in selected_bones:if "_" in bone:new_name = bone.split("_")[0]  # 获取下划线前面的部分作为新的骨骼名称cmds.rename(bone, new_name)  # 重命名骨骼rename_bones()

层级 rename

import maya.cmds as cmdsdef rename_bones_with_suffix(bone, suffix):children = cmds.listRelatives(bone, children=True, type="joint") or []  # 获取骨骼的子骨骼for child in children:rename_bones_with_suffix(child, suffix)  # 递归调用,处理子骨骼new_name = bone + suffix  # 添加结尾字符串cmds.rename(bone, new_name)  # 重命名骨骼print("将骨骼 {} 重命名为 {}".format(bone, new_name))selected_bones = cmds.ls(selection=True, type="joint")  # 获取选中的骨骼for bone in selected_bones:rename_bones_with_suffix(bone, "_R")

属性赋值

左手旋转复制到右手上

import maya.cmds as cmdsdef flip_z_rotation(source_bone, target_bone):# 获取源骨骼的旋转值source_rotation = cmds.getAttr(source_bone + ".rotate")[0]# 翻转旋转值的Z轴flipped_rotation = [source_rotation[0], source_rotation[1], -source_rotation[2]]# 将翻转后的旋转值赋值给目标骨骼cmds.setAttr(target_bone + ".rotate", flipped_rotation[0], flipped_rotation[1], flipped_rotation[2], type="double3")print("将骨骼 {} 的旋转值翻转并赋值到骨骼 {}".format(source_bone, target_bone))all_bones = cmds.ls(type="joint")  # 获取所有骨骼for bone in all_bones:if "_L" in bone:# 替换"_L"为"_R"的骨骼target_bone = bone.replace("_L", "_R")# 检查替换后的骨骼是否存在if cmds.objExists(target_bone):flip_z_rotation(bone, target_bone)

控制台调用批量处理

自己的批量处理框架

# -*- coding: utf-8 -*-import os
import json
import math
import errno
import numpy as np    import maya.cmds as cmds
import pymel.core as pm
import pymel.core.nodetypes as nt
import pymel.core.datatypes as dtfrom maya import mel def SetFPS(fps):unit = 'ntscf'if fps == 15:unit = 'game'elif fps == 24:unit = 'film'elif fps == 25:unit = 'pal'elif fps == 30:unit = 'ntsc'elif fps == 48:unit = 'show'elif fps == 50:unit = 'palf'elif fps == 60:unit = 'ntscf'else:unit = str(fps)+'fps'cmds.currentUnit( time=unit )fps = mel.eval('currentTimeUnitToFPS')# 等价的#mel.eval("currentUnit -time ntsc;")return fpsclass Cls_get_pure_bone:def __init__(self, bones, dstRoot=None, fps=30):self.use_joints = bonesself.dstRoot = dstRootself.fps = fps    def setup(self):cmds.file(new=True, force=True)if self.fps == 30:mel.eval("currentUnit -time ntsc;")self._import_fps = Falseelse:SetFPS(self.fps)self._import_fps = False#self._import_fps = Truedef run(self, animFbx, outFn, targetOnly=True):# import source animationpm.importFile(animFbx, type='FBX',importFrameRate=self._import_fps,importTimeRange='override')startFrame = pm.playbackOptions(animationStartTime=True, q=True)endFrame   = pm.playbackOptions(animationEndTime=True, q=True)def string_array_contains(array, string):for item in array:if item == string:return True  # 包含指定字符串return False  # 不包含指定字符串all_joints=cmds.ls(type="joint")# 遍历所有骨骼for joint in all_joints:# 检查当前骨骼是否在给定的骨骼列表中if not string_array_contains(self.use_joints, joint):# 检查当前骨骼是否在给, joint):# 删除不在列表中的骨骼if cmds.objExists(joint):print("删除骨骼 " + joint)cmds.delete(joint)else:print("骨骼 " + joint + " 不存在")pm.playbackOptions(animationStartTime=startFrame, e=True)pm.playbackOptions(minTime=startFrame, e=True)pm.playbackOptions(animationEndTime=endFrame, e=True)pm.playbackOptions(maxTime=endFrame, e=True)# export retargeted animif targetOnly:pm.select(self.dstRoot)pm.exportSelected(outFn, type='FBX export', force=True)else:pm.exportAll(outFn, type='FBX export', force=True) return outFn  if __name__ == '__main__':import argparseparser = argparse.ArgumentParser()parser.add_argument('--inputAnimFile', type=str, default=None, help='Input Anim Fbx')parser.add_argument('--inputFolder', type=str, default=None, help='Input Fbx Directory, batch mode')parser.add_argument('--outputFolder', type=str, default=None, help='Output Fbx Directory')parser.add_argument('--resume', action='store_true', help='skip exist or redo')parser.add_argument('--targetOnly', action='store_true', help='only keep target char')parser.add_argument('--dstRoot', type=str, default='')parser.add_argument('--fps', type=int, default=30)args = parser.parse_args()file_path = "scripts/data/coco_bone.txt"# 打开文件with open(file_path, "r") as file:# 按行读取文件内容bones = [ e.strip() for e in file.readlines() ]# list input filesif args.inputFolder is None:inputFiles = [args.inputAnimFile]inputFolder = os.path.dirname(args.inputAnimFile)else:from pathlib import Pathif not os.path.isdir(args.inputFolder):# regex pattern in argpattern = os.path.basename(args.inputFolder)inputFolder = os.path.dirname(args.inputFolder)else:# directoryinputFolder = args.inputFolder# pattern = r'**/*_anim.fbx'pattern = r'**/*.fbx'inputFiles = sorted([str(f) for f in Path(r'{0}'.format(inputFolder)).glob(pattern)])if args.outputFolder is None:outputFolder = inputFolderelse:outputFolder = args.outputFoldercls = Cls_get_pure_bone(bones,dstRoot=args.dstRoot,fps=args.fps)cls.setup()for inputFile in inputFiles:relpath  = os.path.relpath(os.path.dirname(inputFile), inputFolder)        fout  = os.path.join(outputFolder, relpath) + f"/{os.path.basename(inputFile)}"ddir=fout.rsplit("/",1)[0]if not os.path.exists(ddir):os.makedirs(ddir)print('-- work on file: {0}'.format(inputFile))if args.resume and os.path.exists(fout):print('-- skip {0}'.format(inputFile))continuecls.run(inputFile, fout)

调用方式

@echo off
setlocalrem "C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" /path/get_pure_bone.py ^--inputFolder  \path\fbx_org ^--dstRoot DeformationSystem ^--outputFolder \path\fbx_org_clear ^--targetOnly --fps 30
http://www.lryc.cn/news/287417.html

相关文章:

  • 数据结构·单链表
  • Redis(秒杀活动、持久化之RDB、AOF)
  • Window安装Python和开发Pycharm
  • 技术驱动宠物健康:宠物在线问诊系统的高效搭建手册
  • 玩转k8s:yaml介绍
  • 【spdk】spdk compressdev测试
  • Linux中并发程序设计(进程的创建和回收、exec函数使用)
  • 2023年DevOps国际峰会暨 BizDevOps 企业峰会(DOIS北京站):核心内容与学习收获(附大会核心PPT下载)
  • pdf 转html 在线预览和查询
  • docker 体验怀旧游戏(魂斗罗等)
  • JS中判断数据类型总结以及方法封装
  • 【Midjourney】绘画风格关键词
  • 教你如何低成本自建「幻兽帕鲁」服务器,快速一键部署
  • 拥抱社交电商浪潮:微信小程序商城崛起引领电商新风向-亿发
  • 一个使用pyqt的word文档查重工具
  • SpringCloud Alibaba Sentinel 与 SpringCloud Gateway 的限流有什么差别?(三种限流算法原理分析)
  • 邦芒忠告:职场新人最需要避开的十大雷坑
  • MySQL-进阶-索引
  • GitLab入门指南:上传与下载操作一网打尽
  • GPT应用_PrivateGPT
  • Qt‘s 撤销框架(Qt‘s Undo Framework)
  • 【C++】stack、queue的使用及模拟实现
  • 外包干了2个多月,技术退步明显。。。。。
  • html5实现好看的年会邀请函源码模板
  • 【C++】反向迭代器模拟实现
  • 【低照度图像增强系列(5)】Zero-DCE算法详解与代码实现(CVPR 2020)
  • 三维重建衡量指标记录
  • 在WinForms中控制模态对话框的关闭行为
  • java web mvc-02-struts2
  • 文件上传之大文件分块上传