#-*-coding:utf-8 -*- from maya import mel from maya import cmds import pymel.core as pm import os import json import datetime as dt from . import modeling from . import common from . import lang from . import weight def main(mesh=None, pop_zero_poly=False): cmds.selectMode(o=True) #pop_zero_poly→ゼロポリゴンメッシュを発見した場合に警告メッセージを出すかどうか msg01 = lang.Lang( en='There is a zero polygon object : ', ja=u'ゼロポリゴンのメッシュが存在します : ') msg02 = lang.Lang( en='As it is in selected state, please process accordingly\n(Recommended to delete)', ja=u'選択状態になっているので適宜処理してください \n(削除推奨)') if mesh is None: selection = cmds.ls(sl=True) selection_l = cmds.ls(sl=True, l=True) else: selection = mesh selection_l = cmds.ls(mesh, l=True) zero_mesh = modeling.cehck_zero_poly_object(mesh=selection, pop_msg=False) #リストタイプじゃなかったらリストに変換する if not isinstance(selection, list): temp = selection selection = [] selection.append(temp) clusterCopy = modeling.ClusterCopy() engine = 'maya' for node, node_l in zip(selection, selection_l): if node in zero_mesh: print 'Skip Zero Triangle Mesh :', node continue #メッシュノードを含むオブジェクトのみ処理する。 meshnode = cmds.listRelatives(node_l, s=True, pa=True, type='mesh', fullPath=True) if meshnode: defCls = clusterCopy.copy(node) bs_dict = store_blend_shape(node) #ブレンドシェイプを保存 copyWeight(node_l, engine=engine ) freezeModeling(node_l, engine=engine ) if defCls: clusterCopy.paste(node) set_blend_shape(node, bs_dict) cmds.select(cl=True) for s in selection: try: cmds.select(s, add=True) except Exception as e: print e.message if zero_mesh and pop_zero_poly: msg = msg01.output()+str(len(zero_mesh)) msg += '\n'+msg02.output() for p in zero_mesh: msg+='\n[ '+p+' ]' cmds.confirmDialog( title="Warning", message=msg ) cmds.select(zero_mesh, r=True) #ブレンドシェイプ情報を保存 def store_blend_shape(mesh): shapes = cmds.listRelatives(mesh, s=True, f=True) skin = cmds.ls(cmds.listHistory(shapes), type='skinCluster') if skin: connections = cmds.listConnections(skin, s=True, d=False) else: connections = cmds.listConnections(shapes, s=True, d=False) blend_shapes = cmds.ls(connections, l=True, type='blendShape') bs_dict = {} if blend_shapes: for bs in blend_shapes: shape_target = cmds.ls(cmds.listConnections(bs, s=True, d=False), l=True, type='transform') bs_dict[bs]=shape_target return bs_dict return def set_blend_shape(mesh, bs_dict): if not bs_dict: return for bs, shape_target in bs_dict.items(): cmds.blendShape(shape_target+[mesh], name=bs, frontOfChain=True) def repareDagSetMember(node): #Dagセットメンバーの接続を修正する、シンメトリウェイトできないとき用。 shadingEngin = get_shading_engines(node) if shadingEngin == []: return shapes = cmds.listRelatives(node, s=True, pa=True, type='mesh') connections = cmds.listConnections(shapes[0], d=True, s=False, p=True, c=True) for con in connections: if shadingEngin[0]+'.dagSetMembers' in con: conAttr = con listIndex = connections.index(con) disconAttr = connections[listIndex-1] cmds.disconnectAttr(disconAttr, conAttr) cmds.connectAttr(shapes[0]+'.instObjGroups[0]', conAttr, f=True) def copyWeight(node, engine='maya'): weight.WeightCopyPaste().main(node, mode='copy', saveName=__name__, engine=engine) def freezeModeling(node, engine='maya'): #子供のノード退避用ダミーペアレントを用意 dummy = common.TemporaryReparent().main(mode='create') common.TemporaryReparent().main(node,dummyParent=dummy, mode='cut') #ヒストリを全削除 cmds.bakePartialHistory(node,pc=True) #ウェイトを書き戻してくる weight.WeightCopyPaste().main(node, mode='paste', saveName=__name__, engine=engine) #いらないシェイプを消す deleteZeroShape(node) #親子付けを戻す common.TemporaryReparent().main(node, dummyParent=dummy, mode='parent') #ダミーペアレントを削除 common.TemporaryReparent().main(dummyParent=dummy, mode='delete') #接続の無い不要なシェイプを削除 def deleteZeroShape(node): meshnode = cmds.listRelatives(node, s=True, pa=True, type='mesh', fullPath=True) for mesh in meshnode: triNum = cmds.polyEvaluate(mesh, triangle=True) historyNode = cmds.listHistory(mesh, f=True) if len(historyNode) <= 1: cmds.delete(mesh) def save_cluster(node): #ノードの中からスキンクラスタを取得してくる#inMesh直上がSkinClusterとは限らないので修正 srcDeformerCluster = cmds.ls(cmds.listHistory(node),type='cluster') if not srcDeformerCluster: return#スキンクラスタがなかったら関数抜ける #スキンクラスタのパラメータ色々を取得しておく srcDeformerCluster = srcDeformerCluster[0] attributes = cmds.listAttr(srcDeformerCluster) weightList = cmds.getAttr(srcDeformerCluster+'.weightList[0]') envelope = cmds.getAttr(srcDeformerCluster+'.envelope') clusterMssage = cmds.getAttr(srcDeformerCluster+'.message') clusterWeight = cmds.getAttr(srcDeformerCluster+'.weightList[0].weights') def freeze(): cmds.selectMode(o=True) selection = cmds.ls(sl=True, type = 'transform') dummy = common.TemporaryReparent().main(mode='create')#モジュールでダミーの親作成 clusterCopy = modeling.ClusterCopy() for sel in selection: allChildren = [sel] + cmds.listRelatives(sel, ad=True)#子供を取得して1つのリストにする polyMesh = common.search_polygon_mesh(allChildren) if polyMesh: for mesh in polyMesh: common.TemporaryReparent().main(mesh, dummyParent=dummy, mode='cut') defCls = clusterCopy.copy(mesh) cmds.bakePartialHistory(mesh,pc=True) if defCls: clusterCopy.paste(mesh) common.TemporaryReparent().main(mesh, dummyParent=dummy, mode='parent')#コピーのおわったメッシュの子供を元に戻す common.TemporaryReparent().main(dummyParent=dummy, mode='delete')#ダミー親削除 cmds.select(selection, r=True) def get_shading_engines(root_node=None): en_list = [] if root_node is None: shapes = pm.ls(type="mesh") else: if isinstance(root_node, (str, unicode)): root_node = pm.PyNode(root_node) shapes = root_node.listRelatives(ad=True, type="mesh") file_nodes = [] for i in shapes: shading_engines = i.shadingGroups() en_list+=shading_engines return list(set(en_list))