abccache

# 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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值