# -*- coding:utf-8 -*-
from maya import cmds
from maya import mel
class SkinMergeSepa():
def __init__(self):
self.UI()
def merge(self):
#マージしたいスキンメッシュを2つ選択して実行。スキンメッシュにヒストリーが残っているとエラーになるので注意!!
selections = cmds.ls(sl=True,l=True)
if not len(selections) == 2:
cmds.error(‘Must select 2objects!!’)
#グループ階層を取得する。selections[0][1:]は1個目に選択したオブジェクト名の最初のバーティカルバーを取り除いたもの。
#要するに|polySphere > polySphereで取得できる。
if “|” in selections[0][1:]:
listA = selections[0].split(“|”)
groupNameA = “|”.join(listA[:-1])
print(groupNameA)
else:
print(u”階層に入っていません!!”)
#最後のオブジェクト名のみ取得する。
objFinalNameA = selections[0].split(“|”)[-1]
#objFinalNameB = selections[1].split(“|”)[-1]
#複製する。
dups = cmds.duplicate(rr=True)
print(“#######################################”)
print(dups)
#複製したメッシュをマージ
mergeMesh = cmds.polyUnite(mergeUVSets=1,centerPivot=True,n=selections[0],ch=1)
print(“#######################################”)
print(mergeMesh)
#結合すると階層から外れるので元の位置に戻す。
if “|” in selections[0][1:]:
cmds.parent(mergeMesh[0],groupNameA)
#ヒストリーを切って、ピボットを原点にする。
cmds.DeleteHistory(mergeMesh[0])
cmds.FreezeTransformations(mergeMesh[0])
cmds.ResetTransformations(mergeMesh[0])
#マージして生成された不要の空ノード削除。
cmds.delete(dups)
#transformの子にメッシュがあるか確かめる。フラグsはシェイプノードを取得。
for i in selections:
shapes = cmds.listRelatives(i, s=True, pa=True, type=’mesh’)
if not shapes:
cmds.error(‘Node has no shape.’)
else:
#選択したノードがバインドされているか調べる。ヒストリーが残っているとスキンクラスターを取得できずエラーになるので注意!!
srcSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False)
if not srcSkinCluster:
cmds.error(‘Select a node that has a skin cluster applied.’)
#selection[0]の今一度取得。
shapes = cmds.listRelatives(selections[0], s=True, pa=True, type=’mesh’)
srcSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False)
#スキンクラスターの各種設定を取得する。1つ目にに選択したスキンメッシュにヒストリーが残っているとスキンクラスターを取得できずエラーになるので注意!!
srcSkinCluster = srcSkinCluster[0]
skinningMethod = cmds.getAttr(srcSkinCluster+’.skm’)
dropoffRate = cmds.getAttr(srcSkinCluster+’.dr’)
maintainMaxInfluences = cmds.getAttr(srcSkinCluster+’.mmi’)
maxInfluences = cmds.getAttr(srcSkinCluster+’.mi’)
bindMethod = cmds.getAttr(srcSkinCluster+’.bm’)
normalizeWeights = cmds.getAttr(srcSkinCluster+’.nw’)
influences = cmds.skinCluster(srcSkinCluster, q=True, inf=True)
#print(influences)
#マージしたメッシュをバインドする。フラグsは、shapeノードがリストされる。フラグpaは、あってもなくてもたぶん変わらない。
shapes = cmds.listRelatives(mergeMesh[0], s=True, pa=True, type=’mesh’)
if not shapes:
cmds.error(‘Node has no shape.’)
dstSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False) #ちゃんとヒストリーを切っておかないとここでエラーになる。
print(dstSkinCluster)
#バインドしてない場合、バインドしてする。
if not dstSkinCluster:
#マージする前のメッシュと同じ条件でがバインドする。
dstSkinCluster = cmds.skinCluster(mergeMesh[0], influences, omi=maintainMaxInfluences, mi=maxInfluences, dr=dropoffRate, sm=skinningMethod, bm=bindMethod, nw=normalizeWeights, tsb=True)
#最後のコピーウェイト時に使用するため文字列に変換。
dstSkinCluster = dstSkinCluster[0]
#print(srcSkinCluster)
#print(dstSkinCluster)
#A部分のウェイトコピーをする。
#Aのバーテックス数を取得。
A_verNum = cmds.polyEvaluate(selections[0], v=True)
cmds.select(selections[0])
mel.eval(“ConvertSelectionToVertices”)
#Aに呼応するバーテックスを選択する。
cmds.select(mergeMesh[0]+”.vtx[0:”+str(A_verNum-1)+”]”, add=True)
#コピーウェイト。ssは、コピー元のスキンクラスターを入れる。dsは、コピー先のスキンクラスターを入れる。でも今回は、ssフラグとdsフラグは使用しない。
cmds.copySkinWeights(surfaceAssociation=’closestPoint’, influenceAssociation=[‘name’, ‘closestJoint’, ‘oneToOne’], normalize=True, noMirror=True)
#B部分のウェイトコピーをする。
#Bのバーテックス数を取得。
B_verNum = cmds.polyEvaluate(selections[1], v=True)
cmds.select(selections[1])
mel.eval(“ConvertSelectionToVertices”)
#Bに呼応するバーテックスを選択する。
cmds.select(mergeMesh[0]+”.vtx[“+str(A_verNum)+”:”+str(A_verNum+B_verNum-1)+”]”, add=True)
#コピーウェイト。ssは、コピー元のスキンクラスターを入れる。dsは、コピー先のスキンクラスターを入れる。でも今回は、ssフラグとdsフラグは使用しない。
cmds.copySkinWeights(surfaceAssociation=’closestPoint’, influenceAssociation=[‘name’, ‘closestJoint’, ‘oneToOne’], normalize=True, noMirror=True)
print(‘Merge’+selections[0]+selections[1]+’with weight.’)
#最後に元メッシュを削除し、マージしたメッシュを最初に選択したオブジェクト名にする。
cmds.delete(selections)
cmds.rename(mergeMesh[0],objFinalNameA)
cmds.select(selections[0])
#フェースを選択して実行。
def sepa(self):
faces = cmds.ls(sl=True,fl=True)
#if not faces or not “.f” in faces[0]: と書いても良い。
if not faces:
cmds.error(‘Must select faces!!’)
elif not “.f” in faces[0]:
cmds.error(‘Must select faces!!’)
#オブジェクト名を取得。
objName = faces[0].split(“.”)
print(“########################################”)
print(objName[0])
##追記部分##
###############################################################
objLastNameA = objName[0].split(“|”)[-1]
###############################################################
#複製する。
dupA = cmds.duplicate(objName[0],rr=True)
dupB = cmds.duplicate(objName[0],rr=True)
#複製したオブジェクトの不要フェースを削除。
deleteFaceA = []
for face in faces:
faceNum = face.split(“.”)
deleteFaceA.append(dupA[0]+”.”+faceNum[1])
cmds.select(deleteFaceA)
cmds.delete()
deleteFaceB = []
for face in faces:
faceNum = face.split(“.”)
deleteFaceB.append(dupB[0]+”.”+faceNum[1])
cmds.select(deleteFaceB)
cmds.InvertSelection()
cmds.delete()
#複製したオブジェクトをまとめる。
dups = [dupA[0],dupB[0]]
#transformの子にメッシュがあるか確かめる。フラグsはシェイプノードを取得。フラグpaは、あってもなくてもたぶん変わらない。
shapes = cmds.listRelatives(objName[0], s=True, pa=True, type=’mesh’)
if not shapes:
cmds.error(‘Node has no shape.’)
#1つ目に選択したノードがバインドされているか調べる。
srcSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False)
if not srcSkinCluster:
cmds.error(‘Select a node that has a skin cluster applied.’)
#スキンクラスターの各種設定を取得する。
srcSkinCluster = srcSkinCluster[0]
skinningMethod = cmds.getAttr(srcSkinCluster+’.skm’)
dropoffRate = cmds.getAttr(srcSkinCluster+’.dr’)
maintainMaxInfluences = cmds.getAttr(srcSkinCluster+’.mmi’)
maxInfluences = cmds.getAttr(srcSkinCluster+’.mi’)
bindMethod = cmds.getAttr(srcSkinCluster+’.bm’)
normalizeWeights = cmds.getAttr(srcSkinCluster+’.nw’)
influences = cmds.skinCluster(srcSkinCluster, q=True, inf=True)
#print(influences)
#セパレイトしたメッシュをバインドする。フラグsは、shapeノードがリストされる。フラグpaは、あってもなくてもたぶん変わらない。
for dup in dups:
shapes = cmds.listRelatives(dup, s=True, pa=True, type=’mesh’)
if not shapes:
cmds.error(‘Node has no shape.’)
dstSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False) #ちゃんとヒストリーを切っておかないとここでエラーになる。
print(dstSkinCluster)
#バインドしてない場合、バインドしていく。
if not dstSkinCluster:
#マージする前のメッシュと同じ条件でがバインドする。
dstSkinCluster = cmds.skinCluster(dup, influences, omi=maintainMaxInfluences, mi=maxInfluences, dr=dropoffRate, sm=skinningMethod, bm=bindMethod, nw=normalizeWeights, tsb=True)
#最後のコピーウェイト時に使用するため文字列に変換。
dstSkinCluster = dstSkinCluster[0]
#print(srcSkinCluster)
#print(dstSkinCluster)
#コピーウェイト。ssは、コピー元のスキンクラスターを入れる。dsは、コピー先のスキンクラスターを入れる。ただし、コピー元とコピー先のオブジェクトを選択すれば、ssフラグとdsフラグは使用しなくても良い。
cmds.copySkinWeights(ss = srcSkinCluster, ds = dstSkinCluster, surfaceAssociation=’closestPoint’, influenceAssociation=[‘name’, ‘closestJoint’, ‘oneToOne’], normalize=True, noMirror=True)
#最後に元メッシュを削除し、マージしたメッシュを最初に選択したオブジェクト名にする。
cmds.delete(objName[0])
##変更部分##
###############################################################
#リネイム後に入れるリスト。
renameObjs = []
#リネイムしていく。
cmds.rename(dupA[0],objLastNameA)
cmds.rename(dupB[0],dupA[0])
”’
for dup in dups:
#renameObjs.append(cmds.rename(obj,objName[0]))という表記でもいける。
finalName = cmds.rename(dup,objName[0])
renameObjs.append(finalName)
”’
cmds.select(dupA[0])
###############################################################
#スキンオブジェクトを一つ選んで実行する。
def dupSkin(self):
selection = cmds.ls(sl=True)
if not selection:
cmds.error(‘Must select a source and a destination skin.’)
elif len(selection) != 1:
cmds.error(‘スキンオブジェクトを1個だけ選択して実行してください!!’)
#transformの子にメッシュがあるか確かめる。フラグsはシェイプノードを取得。
shapes = cmds.listRelatives(selection[0], s=True, pa=True, type=’mesh’)
if not shapes:
cmds.error(‘Node has no shape.’)
#1つ目に選択したノードがバインドされているか調べる。
srcSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False)
if not srcSkinCluster:
cmds.error(‘Select a node that has a skin cluster applied.’)
#スキンクラスターの各種設定を取得する。
srcSkinCluster = srcSkinCluster[0]
skinningMethod = cmds.getAttr(srcSkinCluster+’.skm’)
dropoffRate = cmds.getAttr(srcSkinCluster+’.dr’)
maintainMaxInfluences = cmds.getAttr(srcSkinCluster+’.mmi’)
maxInfluences = cmds.getAttr(srcSkinCluster+’.mi’)
bindMethod = cmds.getAttr(srcSkinCluster+’.bm’)
normalizeWeights = cmds.getAttr(srcSkinCluster+’.nw’)
influences = cmds.skinCluster(srcSkinCluster, q=True, inf=True)
print(influences)
#複製する。
dup = cmds.duplicate(rr=True)
#バインドする。
dstSkinCluster = cmds.skinCluster(dup, influences, omi=maintainMaxInfluences, mi=maxInfluences, dr=dropoffRate, sm=skinningMethod, nw=normalizeWeights, tsb=True)
#最後のコピーウェイト時に使用するため文字列に変換。
dstSkinCluster = dstSkinCluster[0]
print(srcSkinCluster)
print(dstSkinCluster)
#コピーウェイト
cmds.copySkinWeights(ss=srcSkinCluster, ds=dstSkinCluster, surfaceAssociation=’closestPoint’, influenceAssociation=[‘name’, ‘closestJoint’, ‘oneToOne’], normalize=True, noMirror=True)
print(u’スキンオブジェクトを複製しました!’)
cmds.select(dup)
#コピー元、コピー先の順でオブジェクトを選択する。コピー先のオブジェクトは複数でもOK!
def bindCopyWeight(self):
selection = cmds.ls(sl=True)
if not selection:
cmds.error(‘Must select a source and a destination skin.’)
#transformの子にメッシュがあるか確かめる。フラグsはシェイプノードを取得。
shapes = cmds.listRelatives(selection[0], s=True, pa=True, type=’mesh’)
if not shapes:
cmds.error(‘Node has no shape.’)
#1つ目に選択したノードがバインドされているか調べる。
srcSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False)
if not srcSkinCluster:
cmds.error(‘Select a node that has a skin cluster applied.’)
#スキンクラスターの各種設定を取得する。
srcSkinCluster = srcSkinCluster[0]
skinningMethod = cmds.getAttr(srcSkinCluster+’.skm’)
dropoffRate = cmds.getAttr(srcSkinCluster+’.dr’)
maintainMaxInfluences = cmds.getAttr(srcSkinCluster+’.mmi’)
maxInfluences = cmds.getAttr(srcSkinCluster+’.mi’)
bindMethod = cmds.getAttr(srcSkinCluster+’.bm’)
normalizeWeights = cmds.getAttr(srcSkinCluster+’.nw’)
influences = cmds.skinCluster(srcSkinCluster, q=True, inf=True)
print(influences)
#転送先のオブジェクトがバインドされていなかったら、バインドする。
for dst in selection[1:]:
shapes = cmds.listRelatives(dst, s=True, pa=True, type=’mesh’)
if not shapes:
continue #次!次!
dstSkinCluster = cmds.listConnections(shapes[0]+’.inMesh’, s=True, d=False) #ちゃんとヒストリーを切っておかないとここでエラーになる。
print(dstSkinCluster)
if dstSkinCluster:
#ヒストリーが切られてない場合はbreakする!!
if not “skinCluster” in dstSkinCluster[0]:
cmds.error(u’ヒストリーを切ってから実行してください!!’)
break
else:
pass
#バインドしてない場合、バインドしていく。
elif not dstSkinCluster:
dstSkinCluster = cmds.skinCluster(dst, influences, omi=maintainMaxInfluences, mi=maxInfluences, dr=dropoffRate, sm=skinningMethod, nw=normalizeWeights, tsb=True)
cmds.select(cl=True)
#最後のコピーウェイト時に使用するため文字列に変換。
dstSkinCluster = dstSkinCluster[0]
print(srcSkinCluster)
print(dstSkinCluster)
#コピーウェイト
cmds.copySkinWeights(ss=srcSkinCluster, ds=dstSkinCluster, surfaceAssociation=’closestPoint’, influenceAssociation=[‘name’, ‘closestJoint’, ‘oneToOne’], normalize=True, noMirror=True)
print(‘Transfar skin weight ‘ + selection[0] + ‘>’ +dst)
cmds.select(dst,add=True)
def UI(self):
if cmds.window(“SkinMergeSepa”,exists=True):
cmds.deleteUI(“SkinMergeSepa”)
cmds.window(“SkinMergeSepa”,title=u”マージ&セパレイト”,tlb=True,s=True)
cmds.window(“SkinMergeSepa”, edit=True, width=140,height=80)
cmds.columnLayout(adjustableColumn=True,rowSpacing=0)
spV1 = cmds.separator(h=10, w=1, style=’in’, hr=True) #垂直方向のセパレーター。hr=Falseと記述することで垂直方向となる。
cmds.rowLayout(numberOfColumns=1,columnWidth1=(140))
bA1 = cmds.button(label=u”マージ”,command=lambda x:self.merge(), w=140,h=30, bgc=[0.3,0.8,0.3])
cmds.setParent(“..”)#ロウレイアウト終了
spV1 = cmds.separator(h=10, w=1, style=’in’, hr=True) #垂直方向のセパレーター。hr=Falseと記述することで垂直方向となる。
cmds.rowLayout(numberOfColumns=1,columnWidth1=(140))
bA1 = cmds.button(label=u”セパレイト”,command=lambda x:self.sepa(), w=140,h=30, bgc=[0.3,0.7,1.0])
cmds.setParent(“..”)#ロウレイアウト終了
spV1 = cmds.separator(h=10, w=1, style=’in’, hr=True) #垂直方向のセパレーター。hr=Falseと記述することで垂直方向となる。
cmds.rowLayout(numberOfColumns=1,columnWidth1=(140))
bA1 = cmds.button(label=u”複製”,command=lambda x:self.dupSkin(), w=140,h=30, bgc=[0.9,0.9,0.5])
cmds.setParent(“..”)#ロウレイアウト終了
spV1 = cmds.separator(h=10, w=1, style=’in’, hr=True) #垂直方向のセパレーター。hr=Falseと記述することで垂直方向となる。
cmds.rowLayout(numberOfColumns=1,columnWidth1=(140))
bA1 = cmds.button(label=u”バインド&コピーウェイト”,command=lambda x:self.bindCopyWeight(), w=140,h=30, bgc=[0.9,0.6,0.5])
cmds.setParent(“..”)#ロウレイアウト終了
cmds.setParent(“..”)#カラムレイアウト終了
cmds.showWindow(“SkinMergeSepa”)