# coding:utf-8
#2021-7-9 17:50
import maya.cmds as cmds
import maya.mel as mel
import xgenm as xg
import xgenm.xgGlobal as xgg
import xgenm.XgExternalAPI as xge
import shutil
import os,sys,re,subprocess,logging
import pymel.core as pm
def getShapeNode(name):
r = pm.ls(name)
if r:
t = r[0]
if hasattr(t, 'getShape'):
if t.getShape():
return t.getShape().fullPath()
return name
# sys.path.append(os.path.dirname(__file__))
import abcWin
g_xp_keyFrame_mel = ""
allUnEnableDeleteObjs = list()
def xp_abcCache():
simulationRate = 1.0
onceFile = 1
inputCacheFileName = ""
_abcCacheCmd(simulationRate, onceFile, inputCacheFileName)
def _getXgenGeo(): # 获取当前场景内所有的xgen面片
fn = cmds.file(q=1, sn=1)
dir = os.path.dirname(fn)
palettes = xg.palettes()
geo_list = []
for palette in palettes:
xgProjectPath = xg.getAttr('xgProjectPath', palette, "", "") # 返回给定描述的工程目录。
xgDataPath = xg.getAttr('xgDataPath', palette, "", "") # 返回给定描述的数据路径。
xgPalettePath = xgProjectPath + xgDataPath
xgPalettePath.replace('', '')
xgPalettePath = xgPalettePath.replace('${PROJECT}', '')
descriptions = xg.descriptions(palette)
# ~ print descriptions
for des in descriptions:
geo = xg.boundGeometry(palette, des)
# print geo
str = ','.join(geo)
geo_list.append(str)
str = ','.join(geo_list)
# print str
geo_array = str.split(',')
# print geo_array
return geo_array
def xp_setDescriptionCacheFile(palette, description, cacheFile):
cacheFileRight = cacheFile.replace("\\","/")
object = 'SplinePrimitive'
attr = 'cacheFileName'
xg.setAttr(attr, xge.prepForAttribute(cacheFileRight), palette, description, object)
object = 'SplinePrimitive'
attr = 'useCache'
val = 'true'
xg.setAttr(attr, xge.prepForAttribute(val), palette, description, object)
object = 'SplinePrimitive'
attr = 'liveMode'
val = 'false'
xg.setAttr(attr, xge.prepForAttribute(val), palette, description, object)
de = xgg.DescriptionEditor
if de:
de.refresh("Full")
class ABCCacheTool():
def __init__(self):
# self.xp_abcCacheWin()
pass
def addSelToSets(self):
selObjs = cmds.ls(sl=1)
if selObjs:
if not cmds.objExists("abcCacheSets"):
cmds.sets(name="abcCacheSets")
else:
cmds.sets(selObjs, forceElement="abcCacheSets", e=1)
def xp_abcCacheWin(self):
'''
主窗口
'''
if cmds.window("xp_abcCacheWin", ex=1):
cmds.deleteUI("xp_abcCacheWin", window=1)
cmds.window("xp_abcCacheWin", iconName="ACSR", title=u"Abc Cache")
cmds.rowColumnLayout(numberOfColumns=1)
cmds.rowColumnLayout()
cmds.intSliderGrp("xp_abcCacheWin_sampleRate_ISP", min=1, max=10, v=1, fieldMaxValue=100, label=u"每帧采样频率", field=1,
cal=(1, "center"), cw=(1, 80))
cmds.rowColumnLayout()
cmds.rowColumnLayout(nc=2)
ann = u"为空的时候文件会自动命名,手动命名需要用字母开头,中间不要有汉字与空格,不要有除了下划线\"_\"以外的字符."
cmds.text(ann=ann, l=u"输出文件命名", w=80)
cmds.textField("xp_abcCacheWin_cacheFileName_textField", ann=ann, w=320, enable=False)
cmds.setParent('..')
cmds.rowColumnLayout(nc=5)
cmds.text(l=u"", w=80)
cmds.checkBox("xp_abcCacheWin_onceFile_checkBox", l=u"单一文件", v=0,
onCommand='cmds.textField("xp_abcCacheWin_cacheFileName_textField", enable=True, e=True)',
offCommand='cmds.textField("xp_abcCacheWin_cacheFileName_textField", e=True, text="");cmds.textField("xp_abcCacheWin_cacheFileName_textField", enable=False, e=True)')
cmds.checkBox("xp_abcCacheWin_onceObj_checkBox", l=u"单一物体", v=0)
cmds.checkBox("xp_abcCacheWin_vex_checkBox", l=u"顶点缓存", v=0)
cmds.checkBox("xp_abcCacheWin_frame_acsr_checkBox", l=u"帧相对采样", v=0)
cmds.setParent('..')
cmds.separator(style="none", height=10)
cmds.rowColumnLayout(numberOfColumns=3)
cmds.text(ann=ann, l=u"缓存路径:", w=80)
cmds.textField("xp_cachePath_textField", ann=u"导出缓存的路径", w=320, enable=True)
cmds.button(l="..", c=self.selectOutputFolder)
cmds.setParent('..')
cmds.rowColumnLayout(numberOfColumns=3)
cmds.rowColumnLayout(columnWidth=(1, 150), numberOfColumns=3)
cmds.button(ann="", c=lambda *args: self.create_abcCache_button_pro_cmd(), label=u"创建")
# cmds.popupMenu()
# cmds.menuItem(c=lambda *args: self.xp_create_abcCache_button_cmd(), l=u"创建 (旧)")
cmds.setParent('..')
cmds.rowColumnLayout(columnWidth=(1, 30), numberOfColumns=3)
cmds.setParent('..')
cmds.rowColumnLayout(columnWidth=(1, 150), numberOfColumns=3)
cmds.button(ann="", c=lambda *args: cmds.deleteUI("xp_abcCacheWin", window=1), label=u"取消")
cmds.setParent('..')
cmds.setParent('..')
cmds.separator(style="in", height=10)
cmds.rowColumnLayout(nc=10)
cmds.text(h=20, al="left", w=40, l=u" 输出:")
cmds.button(h=20, c=lambda *args: self.xp_abcCache_output_text('replace', ""), l=u"清空", w=40)
cmds.setParent('..')
cmds.setParent('..')
cmds.paneLayout(configuration="single")
cmds.scrollField("xp_create_abcCache_output_text", ed=0, tx="")
cmds.setParent('..')
cmds.rowColumnLayout(numberOfColumns=3)
cmds.rowColumnLayout(columnWidth=(1, 150), numberOfColumns=3)
cmds.button(ann="", c=lambda *args: self.addSelToSets(), label=u"添加对象到选择集")
cmds.setParent('..')
cmds.rowColumnLayout(columnWidth=(1, 30), numberOfColumns=3)
cmds.setParent('..')
cmds.rowColumnLayout(columnWidth=(1, 150), numberOfColumns=3)
cmds.showWindow("xp_abcCacheWin")
def selectOutputFolder(self,*args):
result = cmds.fileDialog2(dialogStyle=2, caption="Select Folder", fileMode=3)
if result:
f = result[0]
cmds.textField("xp_cachePath_textField", e=1,text=f)
def xp_abcCache_output_text(self,mode, inputText):
'''
输出文本到窗口
:param mode: 模式(替换和打印)
:param inputText: str
:return:
'''
if mode == "replace":
cmds.scrollField("xp_create_abcCache_output_text", e=1, tx="")
if cmds.scrollField("xp_create_abcCache_output_text", q=1, ex=1):
viewText = cmds.scrollField("xp_create_abcCache_output_text", q=1, tx=1)
if viewText == "":
newText = inputText
else:
newText = unicode(viewText) + "\n" + inputText
cmds.scrollField("xp_create_abcCache_output_text", e=1, tx=newText)
# def xp_create_abcCache_button_cmd(self):
# '''
# 处理点击创建按钮(旧), 有出动力学曲线和几何体abc, 无法同时选中xgen几个和集合体同时出缓存(用mel文件)
# :return:
# '''
# xp_abcCacheWin_sampleRate_ISP = cmds.intSliderGrp('xp_abcCacheWin_sampleRate_ISP', q=1, v=1)
# simulationRate = 1.0 / xp_abcCacheWin_sampleRate_ISP
# onceFile = cmds.checkBox("xp_abcCacheWin_onceFile_checkBox", q=1, v=1)
# inputCacheFileName = cmds.textField("xp_abcCacheWin_cacheFileName_textField", q=1, tx=1)
# my_sel = cmds.ls(sl=1)
# mode = ""
# for i in range(0, len(my_sel)):
# sel_type = cmds.nodeType(my_sel[i])
# shapes = cmds.listRelatives(my_sel[i], c=1, s=1)
# selShape_type = ""
# if shapes and cmds.objExists(shapes[0]):
# selShape_type = str(cmds.nodeType(shapes[0]))
#
# if sel_type == "xgmPalette" or selShape_type == "xgmDescription":
# mode = "xgenHairSystemCurve"
# else:
# mode = "blendShapeGeo"
#
# if mode == "blendShapeGeo":
# # XToolDir = mel.eval("global string $XToolDir;string $pyTemp=$XToolDir;")
# # mel.eval("source \"" + (XToolDir + "xp_abcCache" + "\""))
# # mel.eval('source \"C:\\Users\\yandudu\\Desktop\\DDScripts\\ydd\\pyqt\\xp_abcCache.mel\"')
# abcCacheMelFile = os.path.join(os.path.dirname(__file__),"EAbcCache.mel").replace("\\","/")
# mel.eval('source "%s"'%abcCacheMelFile)
# mel.eval('xp_abcCacheCmd %s %s "%s"' % (simulationRate, onceFile, inputCacheFileName))
#
# if mode == "xgenHairSystemCurve":
# self.xp_xgenAbcCacheCmd(simulationRate)
def create_abcCache_button_pro_cmd(self):
'''
处理点击创建按钮(新), 有出动力学曲线和几何体abc, 无法同时选中xgen几个和几何体同时出缓存
:return:
'''
xp_abcCacheWin_sampleRate_ISP = cmds.intSliderGrp('xp_abcCacheWin_sampleRate_ISP', q=1, v=1)
simulationRate = 1.0 / xp_abcCacheWin_sampleRate_ISP
onceFile = cmds.checkBox("xp_abcCacheWin_onceFile_checkBox", q=1, v=1)
inputCacheFileName = cmds.textField("xp_abcCacheWin_cacheFileName_textField", q=1, tx=1)
onceObj = cmds.checkBox("xp_abcCacheWin_onceObj_checkBox", q=1, v=1)
vexCache = cmds.checkBox("xp_abcCacheWin_vex_checkBox", q=1, v=1)
frameRelSample = cmds.checkBox("xp_abcCacheWin_frame_acsr_checkBox", q=1, v=True)
my_sel = cmds.ls(sl=1)
mode = ""
for i in range(0, len(my_sel)):
sel_type = cmds.nodeType(my_sel[i])
shapes = cmds.listRelatives(my_sel[i], c=1, s=1)
selShape_type = ""
if shapes and cmds.objExists(shapes[0]):
selShape_type = cmds.nodeType(shapes[0])
if sel_type == "xgmPalette" or selShape_type == "xgmDescription":
mode = "xgenHairSystemCurve"
else:
mode = "blendShapeGeo"
if mode == "blendShapeGeo":
self.abcCacheProCmd(simulationRate, onceFile, inputCacheFileName, onceObj=onceObj, vexCache=vexCache)
if mode == "xgenHairSystemCurve":
self.xp_xgenAbcCacheCmd(simulationRate)
def abcCacheProCmd(self,simulationRate, onceFile, inputCacheFileName, allXgenGeoDic=None, allXgenGeoDicBatch=None,
onceObj=False, vexCache=False):
'''
执行出abc缓存
'''
gv_xp_fm_pathBar = mel.eval("global string $gv_xp_fm_pathBar;string $pyTemp=$gv_xp_fm_pathBar;")
# 获取当前文件名
filePath = cmds.file(q=1, sn=1)
fileExt = os.path.splitext(filePath)[1][1:]
if inputCacheFileName != "":
if not mel.eval('isValidString "%s" "[a-zA-Z][a-zA-Z0-9_]*"' % inputCacheFileName):
self.rightEnCodingOutput(u"\n文件命名包含非法字符")
return
activePanel = cmds.getPanel(withFocus=1)
jso_state = ""
# 孤立选择
if activePanel and "modelPanel" in activePanel:
jso_state = cmds.isolateSelect(activePanel, q=1, state=1)
if not jso_state:
mel.eval('enableIsolateSelect "%s" true' % activePanel)
startFrame = cmds.playbackOptions(q=1, min=1)
endFrame = cmds.playbackOptions(q=1, max=1)
endFrame = endFrame + 1
cmds.currentTime(startFrame)
# 载入AbcImport和AbcExport插件
old_gv_xp_fm_pathBar = cmds.file(q=1,sn=1).replace("\\","/")
# mel.eval('xp_fm_setGlobalVar "%s"' % filePath) # 解析路径
filePath = filePath.replace("\\","/")
# fileCacheFolder = mel.eval('xp_getCacheFolder "%s";' % filePath)
# fileCacheFolder = "D:\\test\\abc"
fileCacheFolder = cmds.textField("xp_cachePath_textField",q=1,tx=1)
if fileCacheFolder == "":
self.rightEnCodingOutput(u"\n请输入导出缓存的路径")
return
fileCacheFolder=fileCacheFolder.replace("\\","/")
fileCacheFolder = fileCacheFolder.replace("\"","")
fileCacheFolder = fileCacheFolder.replace("\'","")
if not os.path.isdir(fileCacheFolder):
os.makedirs(fileCacheFolder)
ls_plugins = cmds.pluginInfo(query=1, listPlugins=1)
count1 = "AbcImport" in ls_plugins
count2 = "AbcExport" in ls_plugins
if not count1:
cmds.loadPlugin("AbcImport")
if not count2:
cmds.loadPlugin("AbcExport")
# 所有视图线框显示
allModelPanels = cmds.getPanel(type="modelPanel")
rememberViewShader = []
if allModelPanels:
for j in range(0, len(allModelPanels)):
rememberViewShader.append(cmds.modelEditor(allModelPanels[j], q=1, displayAppearance=1))
cmds.modelEditor(allModelPanels[j], e=1, displayAppearance="wireframe")
modelWin = cmds.modelEditor(allModelPanels[j], q=1, parent=1)
# 创建abc原始模型显示层并设为不可见
abc_origGeo_Layer = "abc_origGeo_Layer"
if not cmds.objExists(abc_origGeo_Layer):
abc_origGeo_Layer = cmds.createDisplayLayer(e=1, name=abc_origGeo_Layer)
cmds.setAttr(abc_origGeo_Layer + ".visibility", 1)
objectList = cmds.ls(sl=1, l=True)
#==========================================
meshMatList = []
for i in objectList:
shape = getShapeNode(i)
shapellNodes = cmds.listHistory(shape, future=True)
for node in shapellNodes:
if cmds.nodeType(node) == "shadingEngine":
faces = cmds.sets(node, int=node)
for face in faces:
if ".f[" in face:
meshMatList.append({node: face})
#======================================================
abcCacheFilePathInfo = []
for unit in objectList:
isStop = False
if onceFile:
abcGeo_array = []
if inputCacheFileName:
abcCacheFileName = inputCacheFileName
else:
for j in range(0, len(objectList)):
geo_name = mel.eval('shortNameOf "%s"' % objectList[j]) + "_abc"
abcGeo_array.append(geo_name)
abcCacheFileName = "_".join(abcGeo_array).replace(":", "_").replace("|", "_")
isStop = True
else:
abcCacheFileName = mel.eval('shortNameOf "%s"' % unit).replace(":", "_").replace("|", "_") + "_abc"
abcCacheFilePath = fileCacheFolder + "/" + abcCacheFileName + ".abc"
userTempFolder = cmds.internalVar(userTmpDir=1)
abcTempPath = userTempFolder + abcCacheFileName + ".abc"
abcCacheFilePathInfo.append({"src": abcTempPath, "dst": abcCacheFilePath,
"obj": mel.eval('shortNameOf "%s"' % unit).replace(":", "_").replace("|",
"_") + "_abc",
"ari_obj": unit})
sizeBytes = int(mel.eval('sizeBytes "%s"' % abcTempPath))
if sizeBytes > 255:
self.xp_abcCache_output_text("", u"选择的对象命名太长,请手动指定更短的输出文件命名,或者重命名选择的对象,或者去掉勾选\"单一文件\".")
self.rightEnCodingOutput(u"选择的对象命名太长,请手动指定更短的输出文件命名,或者重命名选择的对象,或者去掉勾选\"单一文件\".")
cmds.setAttr(abc_origGeo_Layer + ".visibility", 0)
return
if isStop:
break
abc_blendShapes = []
job = ""
dup_uuid_list = []
tempList = list()
for j in range(0, len(objectList)):
dup_name = mel.eval('shortNameOf "%s"' % objectList[j]).replace(":", "_") + "_abc"
dup_geos = cmds.duplicate(objectList[j], rr=1, n=dup_name)
cmds.editDisplayLayerMembers("defaultLayer", cmds.ls(dup_geos, dag=1), noRecurse=1)
get_uuid = cmds.ls(dup_geos[0], uuid=1)
dup_uuid_list.append(get_uuid[0])
parentNode = cmds.listRelatives(dup_geos[0], p=1, f=1)
if parentNode:
dup_geos = cmds.parent(dup_geos[0], w=1)
if onceObj:
# sel_hi = cmds.ls(objectList[j], dag=True, type="transform")
# dup_hi = cmds.ls(dup_geos[0], dag=True, type="transform")
abc_blendShape = cmds.blendShape(objectList[j], dup_geos[0], o="world", n=str(dup_geos[0]) + "_blendShape")
abc_blendShapes.append(abc_blendShape[0])
bs_weight_attr = cmds.listAttr(str(abc_blendShape[0]) + ".weight", multi=1)
cmds.setAttr(str(abc_blendShape[0]) + "." + str(bs_weight_attr[0]), 1)
tempList.append([objectList[j], str(dup_geos[0]), mel.eval('longNameOf "%s"' % dup_geos[0])])
else:
# 移除复制模型的所有中间对象
dup_geos_leaf_dag = cmds.ls(dup_geos, dag=1, leaf=1, io=1)
if dup_geos_leaf_dag:
cmds.delete(dup_geos_leaf_dag)
# 原模型对复制模型做融合变形
if vexCache:
abc_blendShape = cmds.blendShape(objectList[j], dup_geos[0], o="world",
n=str(dup_geos[0]) + "_blendShape")
else:
if cmds.about(b=True):
abc_blendShape = cmds.blendShape(objectList[j], dup_geos[0], o="world",
n=str(dup_geos[0]) + "_blendShape")
else:
abc_blendShape = cmds.blendShape(objectList[j], dup_geos[0], o="local",
n=str(dup_geos[0]) + "_blendShape")
# print("sssssssssssssssssss",abc_blendShape)
abc_blendShapes.append(abc_blendShape[0])
bs_weight_attr = cmds.listAttr(str(abc_blendShape[0]) + ".weight", multi=1)
cmds.setAttr(str(abc_blendShape[0]) + "." + str(bs_weight_attr[0]), 1)
self.abcCachePro_connectTransform(objectList[j], dup_geos[0])
# 移除所有非Mesh节点
dag = cmds.ls(dup_geos[0], dag=1, leaf=1)
for node in dag:
if cmds.objExists(node):
if cmds.nodeType(node) != "mesh":
cmds.delete(node)
# 移除所有空组
dag = cmds.ls(dup_geos[0], dag=1, type="transform")
for node in dag:
if cmds.objExists(node):
if cmds.nodeType(node) == "transform":
get_dag_mesh = cmds.ls(node, dag=1, type="mesh")
if len(get_dag_mesh) == 0:
cmds.delete(node)
tempList.append([objectList[j], str(dup_geos[0]), mel.eval('longNameOf "%s"' % dup_geos[0])])
# 生成预览视频并保存到Maya文件同路径位置
global g_xp_keyFrame_mel
g_xp_keyFrame_mel = ""
job += ("-frameRange " + str(startFrame) + " " + str(endFrame) + " ")
if cmds.checkBox("xp_abcCacheWin_frame_acsr_checkBox", q=1, v=True):
job += ("-frameRelativeSample -0.2 -frameRelativeSample 0 -frameRelativeSample 0.2 ")
job += ("-step " + str(simulationRate) + " ")
job += ("-uvWrite ")
job += ("-writeColorSets ")
job += ("-writeFaceSets ")
job += ("-worldSpace ")
job += ("-writeVisibility ")
job += ("-eulerFilter ")
# ~ job += ("-writeUVSets ")
if cmds.about(api=1) < 201800:
job += ("-writeCreases ")
elif cmds.about(api=1) >= 201800:
job += ("-autoSubd ")
job += ("-dataFormat ogawa ")
# 创建abc缓存
tempJob = ""
tempMelPerFrameCallback = ""
exportCacheCmd = "AbcExport -verbose "
if onceFile:
for unit in tempList:
tempJob += "-root " + cmds.ls(unit[1], l=True)[0] + " "
tempMelPerFrameCallback += "abcWin.abcCachePro_keyFrameVisable('" + unit[0] + "','" + unit[2] + "'); "
# tempMelPerFrameCallback = tempMelPerFrameCallback.replace("\"", "\\\"")
jobs = tempJob + ("-pythonPerFrameCallback \\\"" + tempMelPerFrameCallback + "\\\" ") + job
jobs += "-file " + abcCacheFilePathInfo[0]["src"] + " "
exportCacheCmd += "-j \"" + jobs + "\" "
# cmds.AbcExport(verbose=True, j=exportCacheCmd)
else:
for unit in tempList:
if not cmds.ls(unit[1], l=True):
continue
tempJob = "-root " + cmds.ls(unit[1], l=True)[0] + " "
tempMelPerFrameCallback = "abcWin.abcCachePro_keyFrameVisable('" + unit[0] + "','" + unit[2] + "'); "
# tempMelPerFrameCallback = "xp_abcCache.abcCachePro_keyFrameVisable(\\\"" + unit[0] + "\\\",\\\"" + unit[2] + "\\\"); "
jobs = tempJob + ("-pythonPerFrameCallback \\\"" + tempMelPerFrameCallback + "\\\" ") + job
for pathInfo in abcCacheFilePathInfo:
if str(unit[0]) == str(pathInfo["ari_obj"]):
jobs += "-file " + pathInfo["src"] + " "
break
exportCacheCmd += "-j \"" + jobs + "\" "
if allXgenGeoDicBatch:
exportCacheCmd += allXgenGeoDicBatch
# 导出abc
# print("exportCacheCmdexportCacheCmdexportCacheCmd,",exportCacheCmd)
mel.eval(exportCacheCmd)
if onceFile:
cmd = ("copy " + "\"" + abcCacheFilePathInfo[0]["src"] + "\" \"" + abcCacheFilePathInfo[0][
"dst"] + "\"").replace("/", "\\")
subprocess.call(cmd, shell=True)
else:
for unit in abcCacheFilePathInfo:
cmd = ("copy " + "\"" + unit["src"] + "\" \"" + unit["dst"] + "\"").replace("/", "\\")
subprocess.call(cmd, shell=True)
if cmds.about(b=True):
try:
cmds.delete(abc_blendShapes)
except Exception as e:
self.rightEnCodingOutput(e)
else:
cmds.delete(abc_blendShapes)
dup_uuid_obj_list = cmds.ls(dup_uuid_list, l=1, uuid=1)
for j in range(0, len(dup_uuid_obj_list)):
self.abcCachePro_disconnectTransformAttr(dup_uuid_obj_list[j])
# faceMat SAVE
# self.abcCachePro_clearMesh(dup_uuid_obj_list[j])
# 对复制出来的几何体重新导入abc缓存
if onceFile:
connect_string = " ".join(dup_uuid_obj_list)
# rightEnCodingOutput(dup_uuid_obj_list)
abcImport_cmd = "AbcImport -mode import -connect \"" + connect_string + "\" \"" + abcCacheFilePathInfo[0][
"dst"].replace("\\","/") + "\""
mel.eval(abcImport_cmd.replace("\\","/"))
self.rightEnCodingOutput(u"\n导入abc:" + abcImport_cmd)
# logging.info(u"\n导入abc:" + abcImport_cmd)
else:
for unit in abcCacheFilePathInfo:
connect_string = unit["obj"]
abcCacheFilePath = unit["dst"].replace("\\","/")
abcImport_cmd = "AbcImport -mode import -connect \"" + connect_string + "\" \"" + abcCacheFilePath + "\""
self.rightEnCodingOutput(abcImport_cmd.replace("\\","/"))
mel.eval(abcImport_cmd.replace("\\","/"))
self.rightEnCodingOutput(u"\n导入abc:" + abcImport_cmd)
if cmds.about(b=True):
global allUnEnableDeleteObjs
allUnEnableDeleteObjs.extend(dup_uuid_obj_list)
cmds.currentTime(startFrame)
for j in range(0, len(dup_uuid_obj_list)):
cmds.select(dup_uuid_obj_list[j])
exportFileBaseName = mel.eval('shortNameOf "%s"' % dup_uuid_obj_list[j]).replace(":", "_").replace("|", "_")
exportFilePath = fileCacheFolder + "/" + exportFileBaseName + "." + fileExt
cmds.file(exportFilePath, typ="mayaAscii", force=1, es=1, op="v=0;")
self.rightEnCodingOutput(u"\n导出Maya文件 " + exportFilePath)
# 为了处理自定义属性有key帧的情况,会在出abc的时候回调记录关键帧在g_xp_keyFrame_mel中,在再出导入abc之后对相关属性key帧
if re.search(r"[a-z]", g_xp_keyFrame_mel):
# print("g_xp_keyFrame_melg_xp_keyFrame_mel,",g_xp_keyFrame_mel)
# rightEnCodingOutput(g_xp_keyFrame_mel)
try:
mel.eval(g_xp_keyFrame_mel)
except Exception as e:
self.rightEnCodingOutput(e)
g_xp_keyFrame_mel = ""
# 还原视图显示
cmds.playbackOptions(by=1)
if allModelPanels:
for j in range(0, len(allModelPanels)):
cmds.modelEditor(allModelPanels[j], e=1, displayAppearance=rememberViewShader[j])
# 原始模型放入原始模型显示层
cmds.editDisplayLayerMembers(abc_origGeo_Layer, objectList, noRecurse=1)
cmds.select(dup_uuid_obj_list)
if jso_state == False:
mel.eval('enableIsolateSelect "%s" true;' % activePanel)
if onceFile:
cmd = "del " + "\"" + abcCacheFilePathInfo[0]["src"] + "\""
cmd = cmd.replace("/", "\\") + " /q"
subprocess.call(cmd, shell=True)
# mel.eval('xp_fm_setGlobalVar "%s"' % old_gv_xp_fm_pathBar)
logging.info(u"\nabc缓存到 " + abcCacheFilePathInfo[0]["dst"].replace("\\","/"))
self.rightEnCodingOutput(u"\nabc缓存到 " + abcCacheFilePathInfo[0]["dst"])
self.xp_abcCache_output_text("", abcCacheFilePathInfo[0]["dst"].replace("\\","/"))
else:
for unit in abcCacheFilePathInfo:
cmd = "del " + "\"" + unit["src"] + "\""
cmd = cmd.replace("/", "\\") + " /q"
subprocess.call(cmd, shell=True)
# mel.eval('xp_fm_setGlobalVar "%s"' % old_gv_xp_fm_pathBar)
logging.info(u"\nabc缓存到 " + unit["dst"].replace("\\","/"))
self.rightEnCodingOutput(u"\nabc缓存到 " + unit["dst"].replace("\\","/"))
self.xp_abcCache_output_text("", unit["dst"].replace("\\","/"))
if allXgenGeoDic:
for j in range(0, len(dup_uuid_obj_list)):
for col, geos in allXgenGeoDic.items():
for _geo in geos:
if mel.eval('shortNameOf "%s"' % _geo).replace(":", "_") + "_abc" in dup_uuid_obj_list[j]:
_temp = cmds.parent(dup_uuid_obj_list[j], col, r=True)
if _temp:
longNameTemp = cmds.ls(_temp, l=True)[0]
if cmds.about(b=True):
cmds.blendShape(longNameTemp, _geo, w=(0, 1), o="world")
else:
cmds.blendShape(longNameTemp, _geo, w=(0, 1))
cmds.setAttr(abc_origGeo_Layer + ".visibility", 0)
def abcCachePro_clearMesh(self,object):
'''
移除所有非Mesh节点与除材质以外的所有连接
:param object:
:return:
'''
cmds.delete(cmds.ls(object, dag=1, leaf=1, io=1))
dag = cmds.ls(object, dag=1, leaf=1)
for node in dag:
if cmds.objExists(node):
ls = cmds.listConnections(node, p=1, d=1, t="objectSet")
if not ls:
continue
for j in range(0, len(ls)):
if cmds.nodeType(ls[j]) == "objectSet":
ci = cmds.connectionInfo(ls[j], dfs=1)
# for k in range(0, len(ci[k])):
if not ci:
continue
for k in range(0, len(ci)):
ci_split = ci[k].split(".")
ci_node = ci_split[0]
if node == ci_node:
cmds.disconnectAttr(ls[j], ci[k])
def abcCachePro_disconnectTransformAttr(self,src):
src_list = self.abcCachePro_listTransformsNode(src)
if not src_list:
return
for i in range(0, len(src_list)):
listAttr = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"]
for j in range(0, len(listAttr)):
ci = cmds.connectionInfo(src_list[i] + "." + listAttr[j], sfd=1)
if ci:
cmds.disconnectAttr(ci, src_list[i] + "." + listAttr[j])
def abcCachePro_listTransformsNode(self,object):
'''
列出对象层次内的所有变换节点
:param object:
:return:
'''
listTsfm = []
ls = cmds.ls(object, dag=1, type="transform", l=1)
for node in ls:
if cmds.nodeType(node, api=1) == "kTransform":
listTsfm.append(str(node))
return listTsfm
def abcCachePro_connectTransform(self,src, des):
'''
连接2个对象的变换
:param src:
:param des:
:return:
'''
src_list = self.abcCachePro_listTransformsNode(src)
des_list = self.abcCachePro_listTransformsNode(des)
if not src_list or not des_list:
return
if len(src_list) == len(des_list):
for i in range(0, len(src_list)):
listAttr = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"]
for j in range(0, len(listAttr)):
if cmds.objExists(des_list[i] + ".t"):
cmds.setAttr(des_list[i] + ".t", l=0)
if cmds.objExists(des_list[i] + ".r"):
cmds.setAttr(des_list[i] + ".r", l=0)
if cmds.objExists(des_list[i] + ".s"):
cmds.setAttr(des_list[i] + ".s", l=0)
cmds.setAttr(des_list[i] + "." + listAttr[j], l=0)
mel.eval("connectAttr -f " + src_list[i] + "." + listAttr[j] + " " + des_list[i] + "." + listAttr[j])
else:
self.rightEnCodingOutput(u"\n来源与目标的mesh数量不一致")
# logging.info(u"\n来源与目标的mesh数量不一致")
def xp_xgenAbcCacheCmd(self,simulationRate):
'''
出引导线缓存
:param simulationRate:
:return:
'''
gv_xp_fm_pathBar = mel.eval("global string $gv_xp_fm_pathBar;string $pyTemp=$gv_xp_fm_pathBar;")
# 获取当前文件名
filePath = cmds.file(q=1, sn=1)
get_cacheFileName_textField = ""
if cmds.control("xp_abcCacheWin_cacheFileName_textField", q=1, ex=1):
get_cacheFileName_textField = cmds.textField("xp_abcCacheWin_cacheFileName_textField", q=1, tx=1)
if get_cacheFileName_textField == "":
useCustomFileName = 0
else:
if mel.eval('isValidString "%s" "[a-zA-Z][a-zA-Z0-9_]*"' % get_cacheFileName_textField):
useCustomFileName = 1
else:
useCustomFileName = 0
# logging.info(u"\n文件命名包含非法字符")
self.rightEnCodingOutput(u"\n文件命名包含非法字符")
getXgmDescription_str = self.xp_getXgmDescriptionSelections()
getXgmDescription_list = getXgmDescription_str.split(",")
if len(getXgmDescription_list) == 0:
do = 0
else:
do = 1
if not do:
return
activePanel = cmds.getPanel(withFocus=1)
iso_state = ""
if activePanel and "modelPanel" in activePanel:
iso_state = cmds.isolateSelect(activePanel, q=1, state=1)
if not iso_state:
mel.eval('enableIsolateSelect "%s" true;' % activePanel)
startFrame = cmds.playbackOptions(q=1, min=1)
endFrame = cmds.playbackOptions(q=1, max=1)
# endFrame = endFrame + 1
# 载入AbcImport和AbcExport插件
# global string $alembicCache_folder;
old_gv_xp_fm_pathBar = gv_xp_fm_pathBar
# mel.eval('xp_fm_setGlobalVar "%s"' % filePath)
# fileCacheFolder = "D:/test/abc"
fileCacheFolder = cmds.textField("xp_cachePath_textField",q=1,tx=1)
if fileCacheFolder == "":
self.rightEnCodingOutput(u"\n请输入导出缓存的路径")
return
fileCacheFolder=fileCacheFolder.replace("\\","/")
fileCacheFolder = fileCacheFolder.replace("\"","")
fileCacheFolder = fileCacheFolder.replace("\'","")
# fileCacheFolder = mel.eval('xp_getCacheFolder "%s";' % filePath)
if not os.path.isdir(fileCacheFolder):
os.mkdir(fileCacheFolder)
ls_plugins = cmds.pluginInfo(query=1, listPlugins=1)
count1 = "AbcImport" in ls_plugins
count2 = "AbcExport" in ls_plugins
if not count1:
cmds.loadPlugin("AbcImport")
if not count2:
cmds.loadPlugin("AbcExport")
# 所有视图线框显示
allModelPanels = cmds.getPanel(type="modelPanel")
rememberViewShader = []
if allModelPanels:
for i in range(0, len(allModelPanels)):
rememberViewShader.append(cmds.modelEditor(allModelPanels[i], q=1, displayAppearance=1))
cmds.modelEditor(allModelPanels[i], e=1, displayAppearance="wireframe")
modelWin = cmds.modelEditor(allModelPanels[i], q=1, parent=1)
abcCacheFilePathInfo = list()
for des in getXgmDescription_list:
palette = xg.palette(str(des))
abcCacheFileName = des.replace(":", "_ns_")
if useCustomFileName:
abcCacheFileName = get_cacheFileName_textField
# abcCacheFilePath = str(fileCacheFolder) + "/" + abcCacheFileName + ".abc"
abcCacheFilePath = os.path.join(str(fileCacheFolder) , abcCacheFileName + ".abc")
_blendShape = abcCacheFileName + "_abcBlendShape"
if cmds.objExists(_blendShape):
if cmds.about(b=True):
cmds.blendShape(_blendShape, e=1, w=(0, 0), o="world")
else:
cmds.blendShape(_blendShape, e=1, w=(0, 0))
userTempFolder = cmds.internalVar(userTmpDir=1)
abcTempPath = userTempFolder + abcCacheFileName + ".abc"
curve_array = self.getXgenHairSystemCurves(des)
if not curve_array:
continue
abcCacheFilePathInfo.append({"src": abcTempPath, "dst": abcCacheFilePath, "obj": curve_array,
"palette": palette, "des": des})
job = ""
job += ("-frameRange " + str(startFrame) + " " + str(endFrame) + " ")
# job += ("-step " + str(simulationRate) + " ")
# job += "-dataFormat ogawa "
job += "-ro -stripNamespaces -uvWrite -writeColorSets -worldSpace -writeUVSets -dataFormat ogawa "
exportCacheCmd = "AbcExport -verbose "
for unit in abcCacheFilePathInfo:
curve_array = unit["obj"]
abcTempPath = unit["src"]
# abcCacheFilePath = unit["dst"]
cmds.select(curve_array)
tempJob = ""
for i in range(0, (len(curve_array))):
tempJob += ("-root " + curve_array[i] + " ")
jobs = job + tempJob
jobs += ("-file " + abcTempPath + " ")
exportCacheCmd += "-j \"" + jobs + "\" "
mel.eval(exportCacheCmd)
for unit in abcCacheFilePathInfo:
curve_array = unit["obj"]
abcTempPath = unit["src"]
abcCacheFilePath = unit["dst"]
cmd = ("copy " + "\"" + abcTempPath + "\" \"" + abcCacheFilePath + "\"")
cmd = cmd.replace("/", "\\")
subprocess.call(cmd, shell=True)
cmd = "del " + "\"" + abcTempPath + "\""
cmd = cmd.replace("/", "\\") + " /q"
subprocess.call(cmd, shell=True)
# mel.eval('xp_fm_setGlobalVar "%s"' % old_gv_xp_fm_pathBar)
# 设置xgen描述导向动画缓存文件属性
#------------------------------------------------------------------------------------------
xp_setDescriptionCacheFile(str(unit["palette"]), str(unit["des"]), str(abcCacheFilePath))
#------------------------------------------------------------------------------------------
self.rightEnCodingOutput(u"\nabc缓存到 " + abcCacheFilePath.replace("\\","/"))
if cmds.control("xp_abcCacheWin_cacheFileName_textField", q=1, ex=1):
self.xp_abcCache_output_text("", abcCacheFilePath.replace("\\","/"))
# 自动将引导线abc缓存导入并混合变形到输出曲线
ns = os.path.splitext(os.path.basename(abcCacheFilePath))[0] + "_abc"
if cmds.namespace(exists=ns):
namespaceEditCmd_mel = os.environ['MAYA_LOCATION'] + "/scripts/others/namespaceEditCmd.mel"
mel.eval("source \"" + namespaceEditCmd_mel + "\"")
mel.eval('namespaceEditorDoDelete "%s"' % ns)
# print('file -i -ns "%s" "%s";' % (ns, abcCacheFilePath.replace("\\","/")))
mel.eval('file -i -ns "%s" "%s";' % (ns, abcCacheFilePath.replace("\\","/")))
abcCurveList = cmds.ls(ns + ":*", type="transform")
abcCurveGrp = cmds.group(abcCurveList, n=ns + "_grp")
# abcCurveList = cmds.ls(ns + ":*", type="nurbsCurve")
# root = mel.eval('rootOf "%s"' % abcCurveList[0])
# abcCurveGrp = cmds.rename(root,ns + "_grp")
outputCurveGrp = mel.eval('firstParentOf %s' % curve_array[0])
self.xp_blendShapeCurveGrp(abcCurveGrp, outputCurveGrp)
if cmds.about(b=True):
global allUnEnableDeleteObjs
if isinstance(abcCurveGrp, list):
allUnEnableDeleteObjs.extend(abcCurveGrp)
else:
allUnEnableDeleteObjs.append(abcCurveGrp)
allUnEnableDeleteObjs.append(unit["palette"])
outputCol = mel.eval('rootOf "%s"' % outputCurveGrp)
if outputCol:
cmds.parent(abcCurveGrp, outputCol)
# 还原视图显示
cmds.playbackOptions(by=1)
if allModelPanels:
for i in range(0, len(allModelPanels)):
cmds.modelEditor(allModelPanels[i], e=1, displayAppearance=rememberViewShader[i])
if activePanel and "modelPanel" in activePanel:
if not iso_state:
try:
mel.eval('enableIsolateSelect "%s" true' % activePanel)
except:
pass
def getXgenHairSystemCurves(self,descr):
'''
根据xgen集合描述获取所有关联引导线
:return: 引导线列表
'''
guides = xg.descriptionGuides(str(descr))
guideShapes = cmds.listRelatives(guides, c=1, s=1)
hs_curves = []
if not guideShapes:
return hs_curves
for i in range(0, len(guideShapes)):
xgmMakeGuide = cmds.listConnections(guideShapes[i], s=1, sh=1, t="xgmMakeGuide")
if not xgmMakeGuide:
continue
if cmds.objExists(xgmMakeGuide[0]):
curveShapes = cmds.listConnections(xgmMakeGuide[0] + ".override", s=1, sh=1)
if curveShapes and cmds.objExists(curveShapes[0]):
tsfm = mel.eval('listTransforms "%s"' % curveShapes[0])
curve = tsfm[0]
hs_curves.append(str(curve))
return hs_curves
def getXgenHairSystemCurves2(self,descr):
'''
根据xgen集合描述获取所有关联引导线
:return: 引导线列表
'''
guides = xg.descriptionGuides(str(descr))
guideShapes = cmds.listRelatives(guides, c=1, s=1)
hs_curves = []
if not guideShapes:
return hs_curves
for i in range(0, len(guideShapes)):
xgmMakeGuide = cmds.listConnections(guideShapes[i], s=1, sh=1, t="xgmMakeGuide")
if not xgmMakeGuide:
continue
if cmds.objExists(xgmMakeGuide[0]):
curveShapes = cmds.listConnections(xgmMakeGuide[0] + ".override", s=1, sh=1)
if curveShapes and cmds.objExists(curveShapes[0]):
tsfm = mel.eval('listTransforms "%s"' % curveShapes[0])
curve = tsfm[0]
hs_curves.append(str(curve))
transList = []
for j in hs_curves:
transList.extend(cmds.listRelatives(j,p=1,f=1))
transList = list(set(transList))
return transList
def xp_getXgmDescriptionSelections(self):
# 从选择对象内过滤出xgen的描述,如果选择的是xgen集合,则获得集合内所有的描述。
curve_array = []
my_sel = cmds.ls(sl=1)
sel_xgmDescription = []
for i in range(0, len(my_sel)):
sel_type = cmds.nodeType(my_sel[i])
shapes = cmds.listRelatives(my_sel[i], c=1, s=1)
selShape_type = ""
if shapes and cmds.objExists(shapes[0]):
selShape_type = cmds.nodeType(shapes[0])
if sel_type == "xgmPalette" or selShape_type == "xgmDescription":
_getXgenHairSystemCurves = self.getXgenHairSystemCurves(my_sel[i])
curve_array = curve_array + _getXgenHairSystemCurves
if sel_type == "xgmPalette":
des_list = xg.descriptions(str(my_sel[i]))
for des in des_list:
sel_xgmDescription.append(str(des))
if selShape_type == "xgmDescription":
tsfm = mel.eval('listTransforms "%s"' % shapes[0])
sel_xgmDescription.append(tsfm[0])
xgmDescriptionStr = ",".join(sel_xgmDescription)
return xgmDescriptionStr
def xp_blendShapeCurveGrp(self,srcGrp, desGrp):
# 将描述生成的abc缓存与毛发的输出曲线做混合变形
src_list = cmds.listRelatives(srcGrp, c=1, type="transform")
des_list = cmds.listRelatives(desGrp, c=1, type="transform")
if not src_list or not des_list:
return
for i in range(0, len(src_list)):
srcSub = src_list[i].split(":")
srcBn = srcSub[- 1]
for j in range(0, len(des_list)):
desSub = des_list[j].split(":")
desBn = desSub[- 1]
if srcBn == desBn:
cmds.reorder(des_list[j], b=1)
if len(src_list) == len(des_list):
if cmds.objExists(srcGrp + "BlendShape"):
cmds.delete(srcGrp + "BlendShape")
if cmds.about(b=True):
cmds.blendShape(srcGrp, desGrp, w=(0, 1), o="world", n=srcGrp + "BlendShape")
else:
cmds.blendShape(srcGrp, desGrp, w=(0, 1), n=srcGrp + "BlendShape")
# blendShape - edit - w 0 1 $bs;
else:
self.rightEnCodingOutput(u"\n源曲线与缓存曲线数量不一致")
# logging.info(u"\n源曲线与缓存曲线数量不一致")
def getGeoSet(self):
allNodes = list()
sets = cmds.objExists("abcCacheSets")
if not sets:
self.rightEnCodingOutput(u"需要命名为abcCache的选择集")
# logging.info(u"需要命名为abcCache的选择集")
return list()
nodes = cmds.sets("abcCacheSets", q=True, nodesOnly=True)
if not nodes:
self.rightEnCodingOutput(u"选择集下没有物体")
# logging.info(u"选择集下没有物体")
return list()
for node in nodes:
allNodes.append(str(node))
return allNodes
def rightEnCodingOutput(self,message):
if cmds.about(b=True):
logging.info(message.encode("gbk"))
else:
logging.info(message)
def getAbcCacheWithBatch(self,allXgDes):
'''
获取指定xgen描述相关的geo
:return:
'''
if not allXgDes:
return
allXgenGeoDic = dict()
for col, allDes in allXgDes.items():
geoGrp = list()
geoList = list()
for des in allDes:
geos = xg.boundGeometry(str(col), str(des))
if not geos:
continue
geoList.extend(geos)
for geo in geos:
cmds.setAttr(geo + ".visibility", 1)
_par = cmds.listRelatives(geos[0], p=True)
if _par:
if cmds.nodeType(_par[0]) == "xgmPalette":
geoGrp.extend(geos)
elif cmds.nodeType(_par[0]) == "transform":
if _par[0] not in geoGrp:
cmds.setAttr(_par[0] + ".visibility", 1)
geoGrp.append(_par[0])
if geoGrp:
allXgenGeoDic[col] = geoGrp
return allXgenGeoDic
def getAllXgenBoundGeoExportJob(self,allXgDes):
sceneFilename = cmds.file(q=True, location=True)
startFrame = cmds.playbackOptions(min=True, q=True)
endFrame = cmds.playbackOptions(max=True, q=True)
exportCmd = ""
for col, allDes in allXgDes.items():
col = str(col)
if not col:
continue
des = allDes
geoList = list()
for d in des:
geos = xg.boundGeometry(col, d)
for geo in geos:
geoList.append(cmds.ls(geo, l=True)[0])
if not geoList:
continue
geoList = list(set(geoList))
colStr = col.replace(":", "__ns__")
cacheFilename = ".".join(os.path.basename(sceneFilename).split(".")[:-1]) + "__" + colStr + ".abc"
outputPath = os.path.join(os.path.dirname(sceneFilename), cacheFilename).replace("\\", "/")
jobStr = "-root "
jobStr += " -root ".join(geoList) + " " + "frameRange %s %s " % (
str(int(startFrame - 10)), str(int(endFrame) + 10))
jobStr += "-uvWrite -attrPrefix xgen -worldSpace -stripNamespaces "
jobStr += "-file " + outputPath
exportCmd += "-j \"" + jobStr + "\" "
return exportCmd
def listReference(self,parentNs=None):
refNodes = list()
for ref in cmds.ls(type="reference"):
if 'sharedReferenceNode' in ref:
continue
elif '_UNKNOWN_REF_NODE_' in ref:
continue
if parentNs:
if not str(ref).startswith(parentNs):
continue
refNodes.append(ref)
return refNodes
def deleteAllRefObj(self,):
allRef = self.listReference()
for ref in allRef:
try:
if not cmds.referenceQuery(ref, rfn=True, topReference=True):
continue
except:
continue
try:
childRefs = cmds.referenceQuery(ref, rfn=True, child=True)
if childRefs:
rFile = cmds.referenceQuery(ref, f=True)
cmds.file(rFile, importReference=True)
for unit in childRefs:
temp = cmds.referenceQuery(unit, rfn=True, child=True)
if temp:
try:
rChildFile = cmds.referenceQuery(unit, f=True)
cmds.file(rChildFile, importReference=True)
except:
self.rightEnCodingOutput(u"从引用导入对象失败:%s" % unit)
continue
for t in temp:
try:
_bottomRefFile = cmds.referenceQuery(t, f=True)
cmds.file(_bottomRefFile, importReference=True)
except:
self.rightEnCodingOutput(u"从引用导入对象失败:%s" % t)
else:
try:
rChildFile = cmds.referenceQuery(unit, f=True)
cmds.file(rChildFile, importReference=True)
except:
self.rightEnCodingOutput(u"从引用导入对象失败:%s" % unit)
else:
rFile = cmds.referenceQuery(ref, f=True)
cmds.file(rFile, importReference=True)
except:
self.rightEnCodingOutput(u"从引用导入对象失败:%s" % ref)
# 删除所有灯光
allLight = cmds.ls(lights=True)
if allLight:
cmds.delete(allLight)
# 删除所有顶层对象
global allUnEnableDeleteObjs
# allUnEnableDeleteObjs.extend(cmds.ls(type="xgmPalette", l=True))
allUnEnableDeleteObjs = cmds.ls(allUnEnableDeleteObjs, l=True)
allUnEnableDeleteObjs = list(set(allUnEnableDeleteObjs))
cmds.select(allDagObjects=True)
allRootObjs = cmds.ls(sl=True, l=True)
deleteObjList = list()
for unit in allRootObjs:
if unit in allUnEnableDeleteObjs:
continue
deleteObjList.append(unit)
cmds.delete(deleteObjList)
self.rightEnCodingOutput(u"删除所有不需要的对象")
for ref in self.listReference():
try:
if not cmds.referenceQuery(ref, isLoaded=True):
try:
_rFile = cmds.referenceQuery(ref, f=True)
cmds.file(_rFile, removeReference=True)
except:
self.rightEnCodingOutput(u"移除卸载引用失败%s" % ref)
except:
self.rightEnCodingOutput(u"移除卸载引用失败%s" % ref)
# def makeFailedJob():
# if os.path.exists(os.path.join(os.environ["tmp"], "submitTaskJobId.txt")):
# with open(os.path.join(os.environ["tmp"], "submitTaskJobId.txt"), "r") as f:
# jobId = f.read().strip()
# if jobId:
# cmd = '"C:\\Program Files\\Thinkbox\\Deadline10\\bin\\deadlinecommand.exe" -FailJob %s' % jobId
# p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stderr=subprocess.PIPE,
# stdout=subprocess.PIPE)
# stdout, stderr = p.communicate()
# logging.info(stderr)
def addObjToDisplayLayer(self):
'''
添加所有xgen集合下的几何体到显示层
:return:
'''
allPalette = cmds.ls(allUnEnableDeleteObjs, type="xgmPalette")
if not allPalette:
return
if not cmds.objExists("xgen_output_geo_layer"):
cmds.createDisplayLayer(empty=True, n="xgen_output_geo_layer", number=1)
for palette in allPalette:
allChildren = cmds.listRelatives(palette, children=True, fullPath=True)
for child in allChildren:
shapes = cmds.listRelatives(child, shapes=True)
if shapes and cmds.nodeType(shapes[0]) == "xgmDescription":
continue
# 加到显示层
cmds.editDisplayLayerMembers("xgen_output_geo_layer", child)
def abcCachePro_getFileTextureNode(selection):
listSG = []
listFtn = []
selectionArray = selection.split(" ")
nodes = cmds.ls(selectionArray, ni=1, dag=1)
listHistory = cmds.listHistory(nodes, f=True)
for i in range(0, len(listHistory)):
if cmds.nodeType(listHistory[i]) == "shadingEngine":
listSG.append(str(listHistory[i]))
listSG = list(set(listSG))
for i in range(0, len(listSG)):
SG = listSG[i]
ls_connect = []
SG_connect_attr_list = ["surfaceShader",
"displacementShader",
"aiSurfaceShader",
"aiVolumeShader",
"rsSurfaceShader",
"rsVolumeShader",
"rsShadowShader",
"rsPhotonShader",
"rsEnvironmentShader",
"rsBumpmapShader",
"rsDisplacementShader"]
for j in range(0, len(SG_connect_attr_list)):
if mel.eval('attributeExists "%s" "%s"' % (SG_connect_attr_list[j], SG)):
ls_connect_tmp = cmds.listConnections(str(SG) + "." + SG_connect_attr_list[j], s=1)
if ls_connect_tmp:
ls_connect = ls_connect + ls_connect_tmp
ls_connect = list(set(ls_connect))
if ls_connect:
for j in range(0, len(ls_connect)):
mat = ls_connect[j]
if cmds.objExists(mat):
listHistory = cmds.listHistory(mat, leaf=1)
for node in listHistory:
if cmds.nodeType(node) != "mesh":
if cmds.nodeType(node) == "file":
listFtn.append(node)
if cmds.nodeType(node) != "transform":
listFtn.append(node)
listFtn = list(set(listFtn))
FileTexture = " ".join(listFtn)
return FileTexture
def abcCachePro_keyframeFileNodeMel(source):
# |LieHuangNvC:Group|LieHuangNvC:Geometry"
global g_xp_keyFrame_mel
ftn = abcCachePro_getFileTextureNode(source)
fileList = ftn.split(" ")
writeString = ""
# for i in range(0, len(fileList)):
# if not fileList[i]:
# continue
# ct = cmds.currentTime(q=1)
# st = cmds.playbackOptions(q=1, min=1)
# attr_list = cmds.listAttr(fileList[i], k=1)
# if attr_list:
# for j in range(0, len(attr_list)):
# if cmds.objExists(fileList[i]):
# attr_sub = attr_list[j].split(".")
# attr_list[j] = attr_sub[0]
# lc = cmds.listConnections(str(fileList[i]) + "." + attr_list[j], s=1)
# if lc:
# if cmds.nodeType(lc[0]) in ["animCurveTU", "transform", "joint", "animCurveUU"] or attr_list[
# j] in ["frameExtension", "frameOffset"]:
# get_value = float(cmds.getAttr(str(fileList[i]) + "." + attr_list[j]))
# connectionInfo = cmds.connectionInfo(str(fileList[i]) + "." + attr_list[j], sfd=1)
# if connectionInfo and ct == st:
# writeString = (writeString + "\n" + "disconnectAttr " + connectionInfo + " " + str(
# fileList[i]) + "." + attr_list[j] + ";")
# writeString = (
# writeString + "\nsetKeyframe -t " + str(ct) + " -v " + str(get_value) + " " + str(
# fileList[i]) + "." + attr_list[j] + ";")
for i in fileList:
if not i:
continue
ct = cmds.currentTime(q=1)
st = cmds.playbackOptions(q=1, min=1)
attr_list = cmds.listAttr(i, k=1)
if attr_list:
for j in attr_list:
if cmds.objExists(i):
attr_sub = j.split(".")
j = attr_sub[0]
lc = cmds.listConnections(str(i) + "." + j, s=1)
if lc:
if cmds.nodeType(lc[0]) in ["animCurveTU", "transform", "joint", "animCurveUU"] or j in ["frameExtension", "frameOffset"]:
get_value = float(cmds.getAttr(str(i) + "." + j))
connectionInfo = cmds.connectionInfo(str(i) + "." + j, sfd=1)
if connectionInfo and ct == st:
writeString = (writeString + "\n" + "disconnectAttr " + connectionInfo + " " + str(
i) + "." + j + ";")
writeString = (
writeString + "\nsetKeyframe -t " + str(ct) + " -v " + str(get_value) + " " + str(
i) + "." + j + ";")
# 为了在自定义属性key帧的时候使用
global g_xp_keyFrame_mel
g_xp_keyFrame_mel = g_xp_keyFrame_mel + "\r\n" + writeString
def getnHairOutputCurves(sel):
curves = cmds.ls(sel,dag=1,s=1,type="nurbsCurve",ni=1)
list_outputCurves_array = []
for i in curves:
conns = cmds.listConnections(i,d=1,sh=1)
if conns:
if cmds.nodeType(conns[0]) == "follicle":
tsfm = mel.eval('listTransforms("%s")'%(i))
list_outputCurves_array.append(tsfm[0])
list_outputCurve = " ".join(list_outputCurves_array)
return list_outputCurve
def abcCachePro_keyFrameVisable(source, destination):
'''
出缓存时执行的回调函数
'''
if source:
#mel.eval('xp_get_nHair_outputCurves "%s"' % source)
nHair = getnHairOutputCurves(source)
nHair_array = nHair.split(" ")
sourceArray = source.split(" ")
else:
nHair_array = list()
sourceArray = list()
# 获取xgen相关联的geo(例如头皮,眉毛)
getXgenGeo = _getXgenGeo()
src_dag_list = cmds.ls(sourceArray, ni=1, dag=1, type="transform")
src_constraint_list = cmds.ls(sourceArray,
et=["parentConstraint",
"pointConstraint",
"orientConstraint",
"scaleConstraint",
"aimConstraint",
"pointOnPolyConstraint",
"geometryConstraint",
"normalConstraint",
"tangentConstraint"],
dag=1)
if src_constraint_list:
for unit in src_constraint_list:
if unit in src_dag_list:
src_dag_list.remove(unit)
for unit in src_dag_list:
if not cmds.listRelatives(unit, c=True):
src_dag_list.remove(unit)
for j in range(0, len(src_dag_list)):
src_dag_list[j] = cmds.ls(src_dag_list[j], l=True)[0]
subArray = src_dag_list[j].split("|")
if getXgenGeo:
found1 = subArray[- 1] in getXgenGeo
else:
found1 = False
found2 = subArray[- 1] in nHair_array
if not found1 and not found2:
do = cmds.listConnections(src_dag_list[j] + ".drawOverride", c=1)
obj_v = cmds.getAttr(src_dag_list[j] + ".v")
layer_v = 0
if not do:
layer_v = 1
elif do and len(do) == 2:
if cmds.nodeType(do[1]) == "displayLayer":
layer_v = cmds.getAttr(do[1] + ".v")
if obj_v and layer_v and cmds.getAttr("%s.visibility" % src_dag_list[j]):
v = 1
else:
v = 0
ns = cmds.ls(src_dag_list[j], sns=True)[1]
des_dag_list = destination + src_dag_list[j].split(source)[-1]
if ns != ":":
des_dag_list = des_dag_list.replace(ns + ":", "")
if cmds.objExists(des_dag_list):
try:
cmds.setAttr(des_dag_list + ".v", v)
cmd = "setKeyframe -t `currentTime -q` -v " + str(v) + " " + des_dag_list + ".v" + ";\n"
mel.eval(cmd)
except:
pass
abcCachePro_keyframeFileNodeMel(source)
if __name__ == '__main__':
ABCCacheTool().xp_abcCacheWin()
abccache
最新推荐文章于 2022-11-30 09:44:31 发布