maya PythonのOpenMaya の Vector で任意の座標からもっとも近い線分上の点を求める

こんな感じの状態、

# -*- coding: utf-8 -*-
import maya.cmds as cmds
from maya import OpenMaya
#任意の1点と線分の両端の座標から線分上のもっとも近い点を返す
def xGetClosestPoint(myPoint, begin, end):
    myVector3D = OpenMaya.MVector(myPoint[0] - begin[0], myPoint[1] - begin[1], myPoint[2] - begin[2])
    baseVector3D = OpenMaya.MVector(end[0] - begin[0], end[1] - begin[1], end[2] - begin[2])
    nDotProduct = myVector3D * baseVector3D
    print("nDotProduct= "+str(nDotProduct))
    if (nDotProduct > 0):
        print("Big if")
        nBaseLength = baseVector3D.length()
        print("nBaseLength= "+str(nBaseLength))
        nProjection = nDotProduct / nBaseLength
        
        if (nProjection < nBaseLength):
            print("small if")
            scaleValue = nProjection / nBaseLength
            print("scaleValue= "+str(scaleValue))
            baseVector3D = baseVector3D * scaleValue
            
            return [begin[0] + baseVector3D[0], begin[1] + baseVector3D[1], begin[2] + baseVector3D[2]]
        else:
            print("small else")
            return end

    else:
        print("Big else")
        return begin;
    

sel = cmds.ls(sl =True)

# get Translate
start = cmds.xform(sel[0],q=1 ,ws =True,t=True)
mid = cmds.xform(sel[1],q=1 ,ws =True,t=True)
end = cmds.xform(sel[2],q=1 ,ws =True,t=True)

# Vector for Translate
#startV = OpenMaya.MVector(start[0] ,start[1],start[2])
#midV = OpenMaya.MVector(mid[0] ,mid[1],mid[2])
#midV = OpenMaya.MVector(end[0] ,end[1],end[2])

c_vPos = xGetClosestPoint(mid, start, end)
cmds.xform("pSphere1",ws =True,translation=(c_vPos[0], c_vPos[1], c_vPos[2]) )

線状に乗った!!

参考URL

野中文雄先生の任意の座標からもっとも近い線分上の点を求める

http://www.fumiononaka.com/TechNotes/Flash/FN1104002.html

MAYAチュートリアル:Pythonで極ベクトルを正しく配置する方法

maya セット(Sets)の概念を理解する

セットとクイック選択セットの 2 つある

ちなみにセットは非破壊(戻せる)、アセットは破壊(戻せない)機能のようだ。

Python

 import maya.cmds as cmds

 いくつかのオブジェクトを作成するーサンプルとして
 cmds.sphere( n="sphere1" ) 
 cmds.cone( n="cone1" ) 

 現在アクティブなものでセットを作成する
 cmds.select( 'sphere1' ) 
 newSet1 = cmds.sets() 
 cmds.select( 'cone1' ) 
 newSet2 = cmds.sets()

 セットのメンバーをクエリする
 cmds.sets( newSet1, q=True )

 2つのセットを含むセットを作成します
 cmds.sets( newSet1, newSet2, name="setOfSets" )

 セットを選択するには、-noExpandフラグを使用する必要があります。さもないと
 代わりにセットのメンバーが選択されます。
 cmds.select( newSet1, noExpand=True ) 
 cmds.ls( selection=True )

 セットのメンバーを選択します
 cmds.select( newSet1 ) 
 cmds.ls( selection=True )

 ballVerticesという名前の頂点セットを作成します。これには含まれます
 球のすべての頂点。
 cmds.sets( 'sphere1', name="ballVertices", vertices=1 ) 
 cmds.select( 'ballVertices' ) 

 2つのセットの和集合を返す
 cmds.sets( newSet2, union=newSet1 )

 セットのリストに共通のメンバーがあるかどうかをテストします
 cmds.sets( 'ballVertices',isIntersecting=newSet1)

 球がセットのメンバーであるかどうかをテストします
 cmds.sets('sphere1',isMember=newSet1)

 球をセットから削除します
 cmds.sets( 'sphere1', remove=newSet1 )

 球がセットのメンバーであるかどうかを再度テストします
 cmds.sets( 'sphere1', isMember=newSet1 )
import maya.cmds as cmds

# いくつかのオブジェクトを作成するーサンプルとして
cmds.sphere( n="sphere1" ) 
cmds.cone( n="cone1" ) 


# 現在アクティブなものでセットを作成する
cmds.select( 'sphere1' ) 
newSet1 = cmds.sets() 
cmds.select( 'cone1' ) 
newSet2 = cmds.sets()

# セットのメンバーをクエリする
cmds.sets( newSet1, q=True )

# 2つのセットを含むセットを作成します
cmds.sets( newSet1, newSet2, name="setOfSets" )

# セットを選択するには、-noExpandフラグを使用する必要があります。さもないと
# 代わりにセットのメンバーが選択されます。
cmds.select( newSet1, noExpand=True ) 
cmds.ls( selection=True )

# セットのメンバーを選択します
cmds.select( newSet1 ) 
cmds.ls( selection=True )

# ballVerticesという名前の頂点セットを作成します。これには含まれます
# 球のすべての頂点。
cmds.sets( 'sphere1', name="ballVertices", vertices=1 ) 
cmds.select( 'ballVertices' ) 

# 2つのセットの和集合を返す
cmds.sets( newSet2, union=newSet1 )

# セットのリストに共通のメンバーがあるかどうかをテストします
cmds.sets( 'ballVertices',isIntersecting=newSet1)

# 球がセットのメンバーであるかどうかをテストします
cmds.sets('sphere1',isMember=newSet1)

# 球をセットから削除します
cmds.sets( 'sphere1', remove=newSet1 )

# 球がセットのメンバーであるかどうかを再度テストします
cmds.sets( 'sphere1', isMember=newSet1 )

重複してたらそのセットから削除してから新規セットに追加する




def unique_obj_sets_make_selected(newSetName):
    #重複してたらそのセットから削除してから新規セットに追加する ---------------------------
    #-------------------------------------------------------------
    selected_arr=cmds.ls(selection=True)#  [pCube9,pCube10,pCube11]
    #newSet01_arr=cmds.sets( "newSet1", q=True )#  [pCube4,pCube5,pCube6]
    #newSet02_arr=cmds.sets( "newSet2", q=True )#  [pCube7,pCube8,pCube9]
    print("selected_arr= "+str(selected_arr))
    #print("newSet01_arr= "+str(newSet01_arr))
    #print("newSet02_arr= "+str(newSet02_arr))
    # python のsetを使ってそれぞれユニーク化する
    selected_set=set(selected_arr)
    #newSet01_set=set(newSet01_arr)
    #newSet02_set=set(newSet02_arr)
    print("selected_set= "+str(selected_set))
    #print("newSet01_set= "+str(newSet01_set))
    #print("newSet02_set= "+str(newSet02_set))
    # old_set を作る(和集合を使う)
    #old_set=newSet01_set | newSet02_set
    #print("old_set= "+str(old_set))
    
    # old_set_full を作る(和集合を使う)
    all_sets=cmds.ls(type="objectSet")
    print("all_sets= "+str(all_sets))
    old_arr_full=[]
    old_set_full=set(old_arr_full)
    for sets_name in all_sets:
        sets_arr=cmds.sets( sets_name, q=True )
        print("sets_arr= "+str(sets_arr))
        
        if(str(sets_arr)=="None"):
            print("None line")
        else:
            print("OK line")
            sets_arr_len=len(sets_arr)
            print("sets_arr_len= "+str(sets_arr_len))
            sets_set=set(sets_arr)
            old_set_full=old_set_full | sets_set
    print("old_set_full= "+str(old_set_full))
    
    # 積集合(共通部分をとる)
    s_intersection = old_set_full & selected_set
    print("s_intersection= "+str(s_intersection))
    list_intersection=list(s_intersection)
    #どこに入ってるかを調べる
    top_all=cmds.ls()
    #------------Get Type Name Code----------- 
    #print("top_all= "+str(top_all))
    #for top_obj in top_all:
    #    objectType=cmds.objectType( top_obj )
    #    print("objectType="+str(objectType)+" top_obj= "+str(top_obj))
    #----------------------------------------
    all_sets=cmds.ls(type="objectSet")
    print("all_sets= "+str(all_sets))
    for sets_name in all_sets:
        set_arr=cmds.sets( "newSet1", q=True )
        for intersect_obj in list_intersection:
            #セットのメンバーであるかどうかをテストします
            isMemberBool=cmds.sets(intersect_obj,isMember=sets_name)
            if(isMemberBool==True):
                print(" sets_name= "+str(sets_name)+" in intersect_obj="+str(intersect_obj))
                #セットから削除します
                cmds.sets( intersect_obj, remove=sets_name )
    
    cmds.select(selected_arr)
    newSet3 =cmds.sets( selected_arr, name=str(newSetName) )
    #newSet3 = cmds.sets() 
    
unique_obj_sets_make_selected("newSet3")

QTreeView Get Selected Text (pyside2)(python3)


# -*- coding: utf-8 -*-
import os
from functools import partial
import time
import imp

"""
PySide2モジュールを探し、ある場合はそちらをインポートします。
"""
try:
    imp.find_module('PySide2')
    from PySide2.QtWidgets import *
    from PySide2.QtGui import *
    from PySide2.QtCore import *

except ImportError:
    from PySide.QtGui import *
    from PySide.QtCore import *


LOGO_IMAGE = r"画像のパスをここに入れてください。"


def get_maya_pointer():
    """
    Mayaのメインウィンドウを取得する関数
    """
    try:
        import maya.cmds as cmds
        from maya import OpenMayaUI

    except ImportError:
        return None

    """
    実は2017ではshibokenも2になっているので、あればshiboken2をインポートします。
    """
    try:
        imp.find_module("shiboken2")
        import shiboken2
        return shiboken2.wrapInstance(int(OpenMayaUI.MQtUtil.mainWindow()), QWidget)

    except ImportError:
        import shiboken
        return shiboken.wrapInstance(int(OpenMayaUI.MQtUtil.mainWindow()), QWidget)





class TreeView_Selected_Text(QMainWindow):


    def __init__(self, parent = None):
        super(TreeView_Selected_Text, self).__init__(parent)
        self.setObjectName("TreeView_Selected_Text")
        self.setWindowTitle("TreeView_Selected_Text")
        self._initUI()
        self.errorDialog = QErrorMessage(self) # QErrorMessageインスタンスの保持


    def _initUI(self):
        wrapper = QWidget()
        self.setCentralWidget(wrapper)

        mainLayout = QVBoxLayout()
        wrapper.setLayout(mainLayout)

        #-----------------------------------------------------------------------

        #-----------------------------------------------------------------------
        # fifth row
        #-----------------------------------------------------------------------
        fifthHorizontalArea = QHBoxLayout()
        fifthHorizontalArea.setSpacing(20)
        mainLayout.addLayout(fifthHorizontalArea)

        fifthHorizontalArea.addWidget(self._makeTreeWidget())

        mainLayout.addWidget(self._makeHorizontalLine())

        #-----------------------------------------------------------------------


    def _makeHorizontalLine(self):
        hline = QFrame()
        hline.setFrameShape(QFrame.HLine)
        hline.setFrameShadow(QFrame.Sunken)
        return hline





    def _makeTreeWidget(self):
        """
        QTreeWidgetを作成する関数
        """
        treeWidget = QTreeWidget()
        headerLabels = ["Name", "Age"]
        treeWidget.setColumnCount(len(headerLabels))
        treeWidget.setHeaderLabels(headerLabels)
        treeWidget.setAlternatingRowColors(True)
        treeData = {
            "Male":[
                {"name":"Taro",     "age":"25"},
                {"name":"Ichiro",   "age":"50"},
                {"name":"Jiro",     "age":"40"}
            ],
            "Female":[
                {"name":"Hanako",   "age":"30"}
            ]
        }

        #for sex, profiles in treeData.iteritems():
        for sex, profiles in treeData.items():
            topItem = QTreeWidgetItem([sex])
            treeWidget.addTopLevelItem(topItem)

            for profile in profiles:
                childItem = QTreeWidgetItem(topItem, [profile.get("name"), profile.get("age")])

        treeWidget.expandAll()
        self.treeWidget=treeWidget
        self.treeWidget.selectionModel().selectionChanged.connect(self.treeWidget_selectionChanged)
        
        return treeWidget
    def treeWidget_selectionChanged(self,selected, deselected):
        print("----treeWidget_selectionChanged-----")
        
        
        for QModelIndex in self.treeWidget.selectedIndexes():
            text = QModelIndex.data(Qt.DisplayRole) # or ix.data()
            print("text= "+str(text))
            
            QModelIndex2=QModelIndex.child(0,0).sibling(0,0)
            text2 = QModelIndex2.data(Qt.DisplayRole)   
            print("text2= "+str(text2))   
            QModelIndex3=QModelIndex.child(0,0).sibling(0,1)
            text3 = QModelIndex3.data(Qt.DisplayRole)   
            print("text3= "+str(text3))   



def start():
    maya_win = get_maya_pointer()
    ui = TreeView_Selected_Text(parent = maya_win)
    ui.show()
    return ui


if __name__ == '__main__':

    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    ui = start()
    app.exec_()

Add Twist Joint Auto -ツイストジョイントの追加を自動化したよ-

このビデオの腕のツイストジョイントの追加を自動化したよ
腕を回転させれば肘ジョイントが伸びスキニングした際に肘が丸くなるのを防ぎます
import maya.cmds as cmds
import pymel.core as pm
import os
class TwistJointClass:


    def MainWay(self):
        
        self.Selected_Joint_Check()
        
    def Selected_Joint_Check(self):
        # need elbowJoint select
        selected = cmds.ls(sl=True,long=True)
        print("01 selected= "+str(selected))
        if(str(selected)=="[]"):
            print("Need Select Elbow Joint!!!!!!!!!!!!!!!!!!")
        else:
            self.elbowJoint_to_twistjoint(selected)
            
            self.elbowJoint_to_drivenkey(selected)
        
    def elbowJoint_to_drivenkey(self,selected):
        elbow_joint_full=selected[0]
        print("02 elbow_joint_full= "+str(elbow_joint_full))
        
        self.select_fullname(elbow_joint_full)
        
        elbow_joint_name =self.get_fullname_to_name(elbow_joint_full)
        elbow_joint_togeJointName = self.make_elbow_toge_joint(elbow_joint_full)
        
        elbow_mode="Genesis8"
        if(elbow_mode=="Genesis8"):
            elbow_way_rz=".ry"# my model
        else:
            elbow_way_rz=".rz"# tutorial
        print("elbow_way_rz= "+elbow_way_rz)

        
        # Key Value 1
        
        destArr=elbow_joint_name+elbow_way_rz
        cmds.setAttr( destArr, 0 )
        
        
        
        
        destArr=elbow_joint_togeJointName+".tx"
        cmds.setAttr( destArr, 0 )    

        destArr=elbow_joint_togeJointName+elbow_way_rz
        cmds.setAttr( destArr, 0 )
        
        # Set DrivenKey
        
        #setDrivenKeyframe -currentDriver lowerarm_r.rotateZ lowerarm_toge_r.translateX;
        fromAttr=elbow_joint_name+elbow_way_rz
        DestAttr=elbow_joint_togeJointName+'.tx'
        cmds.setDrivenKeyframe( DestAttr, currentDriver= fromAttr)
        
        #setDrivenKeyframe -currentDriver lowerarm_r.rotateZ lowerarm_toge_r.rotateZ;
        fromAttr=elbow_joint_name+elbow_way_rz
        DestAttr=elbow_joint_togeJointName+elbow_way_rz
        cmds.setDrivenKeyframe( DestAttr, currentDriver= fromAttr)
        
        # Key Value 2
        SideWay=self.check_Left_Or_Right(elbow_joint_name)
        print("64 SideWay= "+SideWay)
        if(SideWay=="R"):
            destArr=elbow_joint_name+elbow_way_rz
            cmds.setAttr( destArr, 180 )
            
            #setAttr "lowerarm_toge_r.translateX" 4;
            destArr=elbow_joint_togeJointName+".tx"
            cmds.setAttr( destArr, 4 )
            
        if(SideWay=="L"):
            destArr=elbow_joint_name+elbow_way_rz
            cmds.setAttr( destArr, -180 )
            
            #setAttr "lowerarm_toge_r.translateX" 4;
            destArr=elbow_joint_togeJointName+".tx"
            cmds.setAttr( destArr, -4 )
        #setAttr "lowerarm_toge_r.rotateZ" 90;
        #destArr=elbow_joint_togeJointName+elbow_way_rz
        #cmds.setAttr( destArr, 90 )
        
        # Set DrivenKey
        
        #setDrivenKeyframe -currentDriver lowerarm_r.rotateZ lowerarm_toge_r.translateX;
        fromAttr=elbow_joint_name+elbow_way_rz
        DestAttr=elbow_joint_togeJointName+'.tx'
        cmds.setDrivenKeyframe( DestAttr, currentDriver= fromAttr)
        #setDrivenKeyframe -currentDriver lowerarm_r.rotateZ lowerarm_toge_r.rotateZ;
        fromAttr=elbow_joint_name+elbow_way_rz
        DestAttr=elbow_joint_togeJointName+elbow_way_rz
        cmds.setDrivenKeyframe( DestAttr, currentDriver= fromAttr)
        
        # reset joint rz
        
        destArr=elbow_joint_name+elbow_way_rz
        cmds.setAttr( destArr, 0 )
        

        
    def check_Left_Or_Right(self,elbow_joint_name):
        SideWay=""
        jointName_arr=elbow_joint_name.split("_")
        if(jointName_arr[0].lower()=="left"):
            SideWay="L"
        if(jointName_arr[0].lower()=="l"):
            SideWay="L"    
        if(jointName_arr[1].lower()=="left"):
            SideWay="L"
        if(jointName_arr[1].lower()=="l"):
            SideWay="L" 
        if(jointName_arr[0].lower()=="right"):
            SideWay="R"
        if(jointName_arr[0].lower()=="r"):
            SideWay="R"    
        if(jointName_arr[1].lower()=="right"):
            SideWay="R"
        if(jointName_arr[1].lower()=="r"):
            SideWay="R"     
        print("SideWay= "+SideWay)
        return SideWay
    def make_elbow_toge_joint(self,elbow_joint_full):
        elbow_joint_name =self.get_fullname_to_name(elbow_joint_full)
        elbow_joint_togeJointName=self.makeName_togejoint(elbow_joint_name)
        
        elbow_pos=cmds.xform(elbow_joint_full,q=1,ws=1,rp=1)
        print("elbow_pos=" +str(elbow_pos))
        jointName2=cmds.joint( p=(elbow_pos[0], elbow_pos[1], elbow_pos[2]-3) ,absolute=True)
        cmds.rename(jointName2,elbow_joint_togeJointName);
        #cmds.parent( elbow_joint_togeJointName, elbow_joint_full )
        cmds.makeIdentity( apply=True, t=1, r=1, s=1, n=0,pn=1,jointOrient=1)
        
        return elbow_joint_togeJointName
        
    def elbowJoint_to_twistjoint(self,selected):
        elbow_joint_full=selected[0]
        print("02 elbow_joint_full= "+str(elbow_joint_full))
        
        hand_joint_full=self.get_one_child_node(elbow_joint_full)
        print("03 hand_joint_full= "+str(hand_joint_full))
        
        upperarm_joint_arr = cmds.listRelatives(str(elbow_joint_full),parent=True,fullPath=True)
        upperarm_joint_full=upperarm_joint_arr[0]
        print("04 upperarm_joint_full= "+str(upperarm_joint_full))

        #shoulder_joint_arr = cmds.listRelatives(str(upperarm_joint_full),parent=True,fullPath=True)
        #shoulder_joint_full= shoulder_joint_arr[0]
        #print("05 shoulder_joint_full= "+str(shoulder_joint_full))

        self.Elbow_Func(hand_joint_full,elbow_joint_full)
        
        self.Hand_Func(hand_joint_full,elbow_joint_full)
        #---------------------------------------------------------------------------------------
        #---------------------------------  upperarm_joint_full  -------------------------------
        #---------------------------------------------------------------------------------------
        self.UpperArm_Func(elbow_joint_full,upperarm_joint_full)
        
        self.Shoulder_Func(upperarm_joint_full)
            
    def Hand_Func(self,hand_joint_full,elbow_joint_full):
        hand_joint_name =self.get_fullname_to_name(hand_joint_full)
        hand_joint_twistJointName=self.makeName_twistjoint(hand_joint_name)
        
        
        hand_pos=cmds.xform(hand_joint_full,q=1,ws=1,rp=1)
        print("hand_pos=" +str(hand_pos))
        jointName2=cmds.joint( p=(hand_pos[0], hand_pos[1], hand_pos[2]) ,absolute=True)
        cmds.rename(jointName2,hand_joint_twistJointName);
        cmds.parent( hand_joint_twistJointName, elbow_joint_full )
        cmds.makeIdentity( apply=True, t=1, r=1, s=1, n=0,pn=1,jointOrient=1)
        # -------------Hand CONNECT -----------------------------------------------------
        fromAtt=hand_joint_name+".rotateX"
        destArr=hand_joint_twistJointName+".rotateX"
        cmds.connectAttr( fromAtt, destArr )
        #--------------------------------------------------------------------------------
        
    def Elbow_Func(self,hand_joint_full,elbow_joint_full):
        # make joint
        elbow_joint_name =self.get_fullname_to_name(elbow_joint_full)
        elbow_joint_twistJointName=self.makeName_twistjoint(elbow_joint_name)
        
        elbow_pos=cmds.xform(elbow_joint_full,q=1,ws=1,rp=1)
        hand_pos=cmds.xform(hand_joint_full,q=1,ws=1,rp=1)
        print("elbow_pos=" +str(elbow_pos))
        print("hand_pos=" +str(hand_pos))
        
        average_x=(elbow_pos[0]+hand_pos[0])/2
        average_y=(elbow_pos[1]+hand_pos[1])/2
        average_z=(elbow_pos[2]+hand_pos[2])/2
        
        jointName=cmds.joint( p=(average_x, average_y, average_z) ,absolute=True)
        cmds.rename(jointName,elbow_joint_twistJointName);
        #makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 -pn 1;
        cmds.makeIdentity( apply=True, t=1, r=1, s=1, n=0,pn=1,jointOrient=1)
        
        #cmds.joint( elbow_joint_twistJointName, e=True,position=(0, 0, 0) )
    
    
        #-----------------elbow divide --------------------------------------------------
        # 1 
        DivideName=elbow_joint_name+"_Divide"
        cmds.shadingNode('multiplyDivide', asUtility=True, name=DivideName)
        
        fromAtt=hand_joint_full+".rotateX"
        destArr=DivideName+".input1X"
        self.connectAttr_FullPath( fromAtt, destArr )
        # ------------- CONNECT ----------
        # 2 
        fromAtt=DivideName+".outputX"
        destArr=elbow_joint_twistJointName+".rotateX"
        self.connectAttr_FullPath( fromAtt, destArr )
        # 3 ------------- setAttr --------------------------
        destArr=DivideName+".input2X"
        self.setAttr_FullPath( destArr, 0.5 )
        
        
    def UpperArm_Func(self,elbow_joint_full,upperarm_joint_full):
        #upperarm_joint_arr = cmds.listRelatives(str(elbow_joint_full),parent=True,fullPath=True)
        #upperarm_joint_full=upperarm_joint_arr[0]
        self.select_fullname(upperarm_joint_full)
        
        # make joint -----------------------------------------
        upperarm_joint_name =self.get_fullname_to_name(upperarm_joint_full)
        upperarm_joint_twistJointName=self.makeName_twistjoint(upperarm_joint_name)
        
        upperarm_pos=cmds.xform(upperarm_joint_full,q=1,ws=1,rp=1)
        elbow_pos=cmds.xform(elbow_joint_full,q=1,ws=1,rp=1)
        print("upperarm_pos=" +str(upperarm_pos))
        print("elbow_pos=" +str(elbow_pos))
        
        average_x=(elbow_pos[0]+upperarm_pos[0])/2
        average_y=(elbow_pos[1]+upperarm_pos[1])/2
        average_z=(elbow_pos[2]+upperarm_pos[2])/2
        
        jointName=cmds.joint( p=(average_x, average_y, average_z) ,absolute=True)
        cmds.rename(jointName,upperarm_joint_twistJointName);
        #makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 -pn 1;
        cmds.makeIdentity( apply=True, t=1, r=1, s=1, n=0,pn=1,jointOrient=1)
        
        #-----------------Upperarm divide2 --------------------------
        #hand_joint_name=fullName_to_ShortName(hand_joint_full)
        DivideName2=upperarm_joint_name+"_Divide"
        cmds.shadingNode('multiplyDivide', asUtility=True, name=DivideName2)
        # 1  
        fromAtt=upperarm_joint_name+".rotateX"
        destArr=DivideName2+".input1X"
        self.connectAttr_FullPath( fromAtt, destArr )
        # ------------- CONNECT ----------
        # 2  
        fromAtt=DivideName2+".outputX"
        destArr=upperarm_joint_twistJointName+".rotateX"
        self.connectAttr_FullPath( fromAtt, destArr )
        # 3  ------------- setAttr --------------------------
        destArr=DivideName2+".input2X"
        self.setAttr_FullPath( destArr, -0.5 )
        #-----------------Upperarm divide2 --------------------------END
        
    def Shoulder_Func(self,upperarm_joint_full):
        #upperarm_joint_arr = cmds.listRelatives(str(elbow_joint_full),parent=True,fullPath=True)
        #upperarm_joint_full=upperarm_joint_arr[0]
        self.select_fullname(upperarm_joint_full)
        
        # make joint -----------------------------------------
        upperarm_joint_name =self.get_fullname_to_name(upperarm_joint_full)
        shoulder_joint_twistJointName=self.makeName_twistjoint("shoulder_"+upperarm_joint_name)
        
        upperarm_pos=cmds.xform(upperarm_joint_full,q=1,ws=1,rp=1)
        print("upperarm_pos=" +str(upperarm_pos))
        
        jointName=cmds.joint( p=(upperarm_pos[0], upperarm_pos[1], upperarm_pos[2]) ,absolute=True)
        cmds.rename(jointName,shoulder_joint_twistJointName);
        #makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 -pn 1;
        cmds.makeIdentity( apply=True, t=1, r=1, s=1, n=0,pn=1,jointOrient=1)
        
        #-----------------Upperarm divide3 --------------------------
        #hand_joint_name=fullName_to_ShortName(hand_joint_full)
        DivideName3="shoulder_"+upperarm_joint_name+"_Divide"
        cmds.shadingNode('multiplyDivide', asUtility=True, name=DivideName3)
        # 1  
        fromAtt=upperarm_joint_name+".rotateX"
        destArr=DivideName3+".input1X"
        self.connectAttr_FullPath( fromAtt, destArr )
        # ------------- CONNECT ----------
        # 2  
        fromAtt=DivideName3+".outputX"
        destArr=shoulder_joint_twistJointName+".rotateX"
        self.connectAttr_FullPath( fromAtt, destArr )
        # 3  ------------- setAttr --------------------------
        destArr=DivideName3+".input2X"
        self.setAttr_FullPath( destArr, -1 )
        #-----------------Upperarm divide2 --------------------------END
        
    def select_fullname(self,fullname):
        import sys
        
        try:
            cmds.select( fullname)
        except OSError as err:
            print("OS error: {0}".format(err))
        except ValueError:
            print("Could not convert data to an integer.")
        except:
            print("Unexpected error:", sys.exc_info()[0])
            #raise

    def setAttr_FullPath(self, destArr ,value):
        import sys
        
        try:
            cmds.setAttr( destArr, value )
        except OSError as err:
            print("OS error: {0}".format(err))
        except ValueError:
            print("Could not convert data to an integer.")
        except:
            print("Unexpected error:", sys.exc_info()[0])
            #raise

    def fullName_to_ShortName(fullName):
        shortName=""
        fullName_index=fullName.find("|")
        if(fullName_index==-1):
            pass
        else:
            fullName_Arr=fullName.split("|")
            fullName_Len=len(fullName_Arr)
            shortName = fullName_Arr[fullName_Len-1]
            print("shortName= "+shortName)
        return shortName

    def connectAttr_FullPath(self, fromAtt, destArr ):
        import sys

        try:
            cmds.connectAttr( fromAtt, destArr )
        except OSError as err:
            print("OS error: {0}".format(err))
        except ValueError:
            print("Could not convert data to an integer.")
        except:
            print("Unexpected error:", sys.exc_info()[0])
            #raise
        
        
    def get_one_child_node(self,elbow_joint_full):
        hand_joint_full=""
        
        hand_joint_arr = cmds.listRelatives(str(elbow_joint_full),children=True,fullPath=True)
        
        print("02 hand_joint_arr= "+str(hand_joint_arr))
        temp_child_name=hand_joint_arr[0]
        elbow_arr=elbow_joint_full.split("|")
        elbow_len=len(elbow_arr)-1
        elbow_last=elbow_arr[elbow_len]
        print("elbow_last= "+elbow_last)
        temp_arr=temp_child_name.split("|")
        temp_len=len(temp_arr)-1
        temp_elbowlastlen_name=temp_arr[elbow_len]
        temp_elbowlastlen_plusone_name=temp_arr[elbow_len+1]
        print("temp_elbowlastlen_name= "+temp_elbowlastlen_name)
        if(elbow_last==temp_elbowlastlen_name):
            print("same OK temp_elbowlastlen_name= "+temp_elbowlastlen_name)
            print("temp_elbowlastlen_plusone_name= "+temp_elbowlastlen_plusone_name)
            
            #for jname in temp_arr
            buildStr=""
            #for(int i = 0; i < elbow_len+1; i++)
            for i in range(1,elbow_len+1+1):
                jname = temp_arr[i]
                buildStr=buildStr+"|"+jname
            print("buildStr= "+buildStr)
            hand_joint_full=buildStr
        return hand_joint_full
            
    def handJoint_to_twistjoint(self):
        # need hand select
        selected = cmds.ls(sl=True,long=True)
        
        print("01 selected= "+str(selected))
        hand_joint_full=selected[0]
        
        print("02 hand_joint_full= "+str(hand_joint_full))
        """
        hiji_joint_arr = cmds.listRelatives(str(hand_joint_full),parent=True,fullPath=True)
        hiji_joint_full=hiji_joint_arr[0]
        print("03 hiji_joint_full= "+str(hiji_joint_full))
        """
        #hand_joint_name =self.get_fullname_to_name(hand_joint_full)
        #hiji_joint_name =self.get_fullname_to_name(hiji_joint_full)
        
        
        #hiji_twistJointName=self.makeName_twistjoint(hiji_joint_name)
        
        #cmds.select(hiji_joint_full)
        #cmds.insertJoint( 'joint2' )
        
        #あとで復帰
        #cmds.select(selected)
        #cmds.select(hand_joint_full)
        
        
    def makeName_twistjoint(self,joint_name):
        
        joint_name_arr=  joint_name.split("_")
        twistJointName=joint_name_arr[0]+"_twist_"+joint_name_arr[1]
        print("twistJointName= "+twistJointName)
        return twistJointName
        
    def makeName_togejoint(self,joint_name):
        
        joint_name_arr=  joint_name.split("_")
        togeJointName=joint_name_arr[0]+"_toge_"+joint_name_arr[1]
        print("togeJointName= "+togeJointName)
        return togeJointName
     
    def get_fullname_to_name(self,fullname):
        hand_joint_full_arr=fullname.split("|")
        print("04 hand_joint_full_arr= "+str(hand_joint_full_arr))
        hand_joint_full_len=len(hand_joint_full_arr)
        hand_joint_jointName=hand_joint_full_arr[hand_joint_full_len-1]
        print("05 hand_joint_jointName= "+str(hand_joint_jointName))
        return hand_joint_jointName

ClassIns= TwistJointClass()
ClassIns.MainWay()

揺れもの YURAYURA.pyのおすすめ設定方法


A-s-C-e-n-S-i-o-N本家さん

http://a-s-c-e-n-s-i-o-n.blogspot.com/2017/12/maya-yurayurapy.html

maya : 骨にヘアを揺れ物シミュレーションするツール YURAYURA.pyの説明
髪の毛などの数珠繋ぎ階層にヘアシミュレーションをかける揺れ物ツールです。

YURAYURAのおすすめ設定というか、揺れすぎていろんな破滅を起こすので
一番ゆれない状態から設定していくのがいいかもしれないと思い、
一番揺れない設定にしてみた。(ゆれるけど)
といってもnHAIRの設定を見たらわかる。

https://knowledge.autodesk.com/ja/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2016/JPN/Maya/files/GUID-89B58075-7927-4117-8D5E-5FECE5669108-htm.html

■■■GENERATE■■■:
髪の毛のルートを選択して、GENERATEボタンを押すと
YURAYURAシミュレーションセットが作られます。
複数選択でき、一度作成した後でも追加で使用できます。

■■■SETTING■■■:

■Gravity:
重力
■Start Curve Attract
開始カーブに引き付け(Start Curve Attract)
現在のヘアの位置を(変形する)開始位置へ引き付ける量を決定します。このアトリビュートは、たとえば、硬めのヘアやキャラクタとともに動くヘアの場合など、多くのヘア ワークフローで役立ちます。さらに、キーフレームを設定されたアニメーションを開始カーブに配置する場合、開始カーブに引き付け(Start Curve Attract)アトリビュートを使用して、シミュレーションと開始カーブ アニメーションをブレンドすることができます。

流れるような長いヘアの場合には、通常、開始カーブに引き付け(Start Curve Attract)の値はゼロのままにします。ただし、短いヘアの場合は、ヘアの十分な剛性を保つことが困難になる場合があります。ヘアの剛性を非常に大きくして、同時に、いくつかのダイナミックなプロパティを持たせる必要がある場合、ゼロより大きい値を使用します。1.0 の値のとき、ヘア位置はカーブ開始位置です(トランスフォームされる毛根からの相対位置になります)。衝突およびフォースだけは、ヘアを偏向させます。Start Curve Attract がない場合、Substep と Damp の値を増やす必要があります(特に、ヘアごとの CV の数が多いとき)。

■Attraction Damp:
引き付けのダンプ(Attraction Damp)
開始カーブに引き付け(Start Curve Attract)のエフェクトをダンプし、ヘアをカーブの開始位置の方に移動させて、ヘアの速度を遅くします。これは、ヘアの弾力性(開始カーブに引き付け(Start Curve Attract)の値が高い場合に発生)を小さくしたい場合や、アニメートされたヘアの頂点にダイナミック フィールドを適用したい場合に便利です。引き付けのダンプ(Attraction Damp)を 1 にすると、開始カーブの方に移動するヘアの動きは完全にダンプされ、開始位置(Start Positions)とフィールド フォースだけをそのままにして、後から任意でその動きにインフルエンスを及ぼせるようにします。

■Drag:
ドラッグ(Drag)
これは、シミュレーションを安定させるのに役立つだけではなく、空気摩擦をシミュレートします。ドラッグ(Drag)の値が 1.0 のとき、ヘアは慣性のモーションやフォロースルーがないように動作するため、粘度が高い液体の中にあるかのように動きます。
■Tangential Drag:
接線のドラッグ(Tangential Drag)
ヘアの方向に沿ってドラッグする量を指定します。0 に設定すると、ヘアは接線方向またはシェイプの方向に沿った移動において抵抗がなくなります。接線のドラッグ(Tangential Drag)を 1 に設定すると、ドラッグ(Drag)はすべての方向に均一になります。ドラッグ(Drag)のレベルが高く、接線のドラッグ(Tangential Drag)が低い場合、ヘアは水中を移動する蛇のような揺らぎモーションの動きをします。
■Motion Drag:
モーション ドラッグ(Motion Drag)
毛根の動きに相対的なヘア カーブの動きをダンプします。モーション ドラッグ(Motion Drag)の値は、ヘア カーブが毛根に合わせて動く量、またヘアのシェイプが他のフォースに影響される程度を決定します。これにより、Substeps の数を増やさなくても、ボビングやウィグルのようなヘアの余分な動きをダンプすることができます。

たとえば、モーション ドラッグ(Motion Drag)を 1.0 に設定すると、ヘアは毛根に合わせて動くので、周囲の大気をそれに合わせてドラッグしているように見えます。
■Damp:
ダンプ(Damp)
ヘアのベンドおよび伸長の方法に影響する個々のヘアの相対的シェイプの変化をダンピングします。
■Stretch Damp:
伸長のダンプ(Stretch Damp)
ヘア カーブ頂点間の伸長による速度がどのくらいダンピングされるかを指定します。伸長のダンプ(Stretch Damp)を大きくすると、ヘアは弾まずに伸長できます。
■■■MODIFY■■■:
SETTING欄の数値を変更して、下にあるMODIFY SETTING ( REFRESH )
ボタンで適用できます。

■■■COLLIDE■■■:
コリジョンをセットしたい場合は、コリジョンオブジェクトを選択して
ADD COLLIDEボタンを押します。

■■■BAKE■■■:
シミュレーション結果が良さそうであれば、BAKEボタンを押すと
元に選択していた階層すべてのRotateにBake Simulationをかけます。
YURAYURAシミュレーションセットは消去され、UIも閉じます。

HumanIK Effector Ctrl AnimationExporter/importer

HumanIKのコントローラーのRIGアニメーション作成は楽しいので昔のKeyFrameを新しいファイルに入れたいときに使う。

animでもatomでも持っていけなかったのでに作るしかないかーと思った。

どうしてもRigなので引っ張られている分ポーズがまんま持っていけるわけではないので確認と調整が必要、ポーズによってはそのまま使える

OKなポーズ

NGだったポーズ

ほとんどNGやないかい。まあ大体の大枠のポーズはインポートできてる。
膝のまがりとかがダメだった。

腰の位置にキーが入らないというかそこらへんが問題ある
HumanIKのHipはへんな記事があった。
HumanIKヒップエフェクターが壊れています
https://forums.cgsociety.org/t/humanik-hip-effector-broken/1583635/3
によると設定をデフォルトにすると直るとか直らないとか神のみぞ知るとか。。

まあとりあえずソース公開

HumanIK Effecter Ctrl Animation Exporter

import maya.cmds as cmds

class HumanIK_Effecter_Ctrl_AnimationExporter:
	def MainWay(self):

		selects=cmds.ls(sl=True)
		selectRef=selects[0]
		print("selectRef= "+selectRef)

		_CtrlIndex=selectRef.find("_Ctrl")
		print("_CtrlIndex= "+str(_CtrlIndex))

		SkeletonName=selectRef[0:_CtrlIndex]
		print("SkeletonName= "+SkeletonName)

		HipsCtrlName=SkeletonName+"_Ctrl_Hips"
		print("HipsCtrlName= "+HipsCtrlName)
		
		startFrame=185
		endFrame=206


		self.keyAllLineStr=""
		
		self.NodeAllLoop(selectRef,HipsCtrlName,startFrame,endFrame)
	
	def key_to_add_line(self,CtrlNode,Way,key_arr):
		if(str(key_arr)=="None"):
			pass
		else:
			 key_arr.insert(0, Way)
			 key_arr.insert(0, CtrlNode)
			 key_str_arr=[]
			 #1度数値を文字列に変換する
			 for v in key_arr:
				str_v=str(v)
				key_str_arr.append(str_v)
			 key_arr_str=",".join(key_str_arr)
			 
			 print("key_arr_str= "+key_arr_str)
			 self.keyAllLineStr=self.keyAllLineStr+key_arr_str+"\n"

	def NodeAllLoop(self,selectRef,HipsCtrlName,startFrame,endFrame):
		
		# 指定したノード以下全てを検索
		CtrlNodeAll=cmds.ls(HipsCtrlName,dag=1)
		#CtrlNodeAll=cmds.ls(selectRef,dag=1)
		print("CtrlNodeAll= "+str(CtrlNodeAll))
		
		CtrlNodeAll.insert(0,selectRef)
		
		for CtrlNode in CtrlNodeAll:
			keyFrameData=""
			#0〜20の時間範囲内のオブジェクト「surface1」のすべてのキーフレームをクエリします。
			#
			keyFrames_rx = cmds.keyframe( CtrlNode,at='rx', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			keyFrames_ry = cmds.keyframe( CtrlNode,at='ry', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			keyFrames_rz = cmds.keyframe( CtrlNode,at='rz', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			
			self.key_to_add_line(CtrlNode,"rx",keyFrames_rx)
			self.key_to_add_line(CtrlNode,"ry",keyFrames_ry)
			self.key_to_add_line(CtrlNode,"rz",keyFrames_rz)
			#print("keyFrames_rx= "+str(keyFrames_rx))
			#print("keyFrames_ry= "+str(keyFrames_ry))
			#print("keyFrames_rz= "+str(keyFrames_rz))

			keyFrames_tx = cmds.keyframe( CtrlNode,at='tx', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			keyFrames_ty = cmds.keyframe( CtrlNode,at='ty', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			keyFrames_tz = cmds.keyframe( CtrlNode,at='tz', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			#keyFrames=cmds.keyframe( sel、time =(185,206)、query = True、valueChange = True、timeChange = True);

			self.key_to_add_line(CtrlNode,"tx",keyFrames_tx)
			self.key_to_add_line(CtrlNode,"ty",keyFrames_ty)
			self.key_to_add_line(CtrlNode,"tz",keyFrames_tz)

			#print("keyFrames_tx= "+str(keyFrames_tx))
			#print("keyFrames_ty= "+str(keyFrames_ty))
			#print("keyFrames_tz= "+str(keyFrames_tz))
			
			keyFrames_sx = cmds.keyframe( CtrlNode,at='sx', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			keyFrames_sy = cmds.keyframe( CtrlNode,at='sy', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			keyFrames_sz = cmds.keyframe( CtrlNode,at='sz', time=(startFrame,endFrame), query=True, valueChange=True, timeChange=True);
			
			self.key_to_add_line(CtrlNode,"sx",keyFrames_sx)
			self.key_to_add_line(CtrlNode,"sy",keyFrames_sy)
			self.key_to_add_line(CtrlNode,"sz",keyFrames_sz)
			
		print("self.keyAllLineStr ="+ self.keyAllLineStr)
		self.fileWrite()
		
	def fileWrite(self):
		
		import codecs

		fout = codecs.open('C:/Users/whaison/Documents/maya/2016/ja_JP/scripts/python/MotionMerge/p030motionbuilder_chimera_0_Start/HumanIK_Effecter_Ctrl_AnimationExporter_keyFrameData.csv', 'w', 'utf_8')
		fout.write(self.keyAllLineStr)




ClassIns = HumanIK_Effecter_Ctrl_AnimationExporter()
ClassIns.MainWay()

HumanIK Effecter Ctrl Animation Importer

import maya.cmds as cmds

class HumanIK_Effecter_Ctrl_AnimationImporter:
	def MainWay(self):

		selects=cmds.ls(sl=True)
		selectRef=selects[0]
		print("selectRef= "+selectRef)

		_CtrlIndex=selectRef.find("_Ctrl")
		print("_CtrlIndex= "+str(_CtrlIndex))

		SkeletonName=selectRef[0:_CtrlIndex]
		print("SkeletonName= "+SkeletonName)

		HipsCtrlName=SkeletonName+"_Ctrl_Hips"
		print("HipsCtrlName= "+HipsCtrlName)
		
		startFrame=185
		endFrame=206


		self.keyAllLineStr=""
		
		#self.NodeAllLoop(HipsCtrlName,startFrame,endFrame,)
		
		self.fileReader()
		
		
	def fileReader(self):
		
		import codecs
		fin = codecs.open('C:/Users/whaison/Documents/maya/2016/ja_JP/scripts/python/MotionMerge/p030motionbuilder_chimera_0_Start/HumanIK_Effecter_Ctrl_AnimationExporter_keyFrameData.csv', 'r', 'utf_8')
		for line in fin:
			print("line= "+line)
			if(line==""):
				pass
			else:
				self.line_to_setkeyframe(line)
			
	
	def line_to_setkeyframe(self,line):
		key_arr=line.split(",")
		CtrlName=key_arr[0]
		print("CtrlName= "+CtrlName)
		Way=key_arr[1]
		print("Way= "+Way)
		key_arr_len=len(key_arr)
		frameStr=""
		valueStr=""
		for i in range(2,key_arr_len):
			val=key_arr[i]
			
			if i % 2 == 0:
				print('frame= '+val)
				frameStr=val
				framefloat=float(frameStr)
			else:
				print('Value= '+val)
				valueStr=val
				valuefloat=float(valueStr)
				print('cmds.setKeyframe( '+CtrlName+","+Way+",t="+str(framefloat)+",v="+str(valuefloat)+")")
				try:
					cmds.setKeyframe( CtrlName, attribute=Way, t=framefloat,v=valuefloat)
				except OSError as err:
					print("OS error: {0}".format(err))
				except ValueError:
					print("Could not convert data to an integer.")
				except:
					print("Unexpected error:", sys.exc_info()[0])
					raise
				
	
	def NodeAllLoop(self,HipsCtrlNam,startFrame,endFramee):
		
		# 指定したノード以下全てを検索
		CtrlNodeAll=cmds.ls(HipsCtrlName,dag=1)
		print("CtrlNodeAll= "+str(CtrlNodeAll))
		
		for CtrlNode in CtrlNodeAll:
			pass
"""
keyFrames_rx= [185.0, 21.089741780299963, 186.0, 21.15808805587963, 187.0, 21.57269253024709, 188.0, 15.651666434240237, 189.0, -27.60824368710669, 190.0, -66.8640151602632, 191.0, -3.6033652533432057, 192.0, -12.976039746033836, 193.0, 21.089741780299963, 206.0, 21.089741780299963]
keyFrames_ry= [185.0, 64.06950181042265, 186.0, -43.06801204369242, 187.0, -42.23534535644165, 188.0, 6.3003207259776, 189.0, -18.619267402281043, 190.0, -46.39726736167605, 191.0, 7.25455667934068, 192.0, 22.112923704038533, 193.0, 64.06950181042265, 206.0, 64.06950181042265]
keyFrames_rz= [185.0, -39.35273351243995, 186.0, -71.88505367073185, 187.0, -71.23919938208138, 188.0, -12.884469861914607, 189.0, -23.728143045065494, 190.0, 1.5441603410596807, 191.0, -29.38106191819622, 192.0, 27.959038658924545, 193.0, -39.35273351243995, 206.0, -39.35273351243995]

#tx
keyFrames_tx= [185.0, -31.063541412353516, 186.0, 13.386266787875757, 187.0, 12.569612782818957, 188.0, -68.13177446430325, 189.0, -14.078931727868042, 190.0, 34.98399964606946, 191.0, -58.035783944634446, 192.0, 38.62583642912938, 193.0, -31.063541412353516, 206.0, -31.063541412353516]
keyFrames_ty= [185.0, 103.91255187988281, 186.0, 160.48102799110984, 187.0, 135.33789404307092, 188.0, 123.42318340077544, 189.0, 143.61781646990772, 190.0, 162.44752777221774, 191.0, 147.59765966522042, 192.0, 149.99067818831213, 193.0, 103.91255187988281, 206.0, 103.91255187988281]
keyFrames_tz= [185.0, -13.255008697509766, 186.0, 126.81360281638925, 187.0, 114.12469622889218, 188.0, 62.25401426920391, 189.0, 116.16546039338427, 190.0, 124.82832123482547, 191.0, 79.97223357269715, 192.0, 43.964009286900165, 193.0, -13.255008697509766, 206.0, -13.255008697509766]

cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_Reference', attribute='translateX', t=186.0,v=-27.940739594423125,)
cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_Reference', attribute='rotationX', t=186.0,v=-27.940739594423125,)
cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_Reference', attribute='rx', t=186.0,v=-27.940739594423125,)

cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_RightArm', attribute='rx', t=185.0,v=21.15808805587963)
cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_RightArm', attribute='ry', t=185.0,v=-43.06801204369242)
cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_RightArm', attribute='rz', t=185.0,v=-71.88505367073185)
#translate
cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_RightWristEffector', attribute='tx', t=186.0,v= 13.386266787875757)
cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_RightWristEffector', attribute='ty', t=186.0,v=160.48102799110984)
cmds.setKeyframe( 'group_meshHIK_TposeSK_Ctrl_RightWristEffector', attribute='tz', t=186.0,v=126.81360281638925)
"""
ClassIns=HumanIK_Effecter_Ctrl_AnimationImporter()
ClassIns.MainWay()

スキンウェイトに詳しくなりたい2 deformerWeights コマンド

https://area.autodesk.jp/column/tutorial/maya_atoz/save-load-skin-weight/にあった最新のスキンウェイトのコピー方法

//XMLexport
deformerWeights -export -deformer “group_mesh|Mesh|Genesis8FemaleSkin” -format “XML” -path “C:/Download/Game/UE4_SK_Mannequin_Motions/scenes/OneTimeLine/” “Genesis8FemaleSkin.xml”;

//XMLimport
deformerWeights -import -method “index” -deformer “group_meshHIK|Mesh|Genesis8FemaleSkin” -path “C:/Download/Game/UE4_SK_Mannequin_Motions/scenes/OneTimeLine/” “Genesis8FemaleSkin.xml”;
skinCluster -e -forceNormalizeWeights “group_meshHIK|Mesh|Genesis8FemaleSkin”; // オプション設定でNormalize weightsがオンだった場合この行も実行。

Maya2016でだと
// エラー: line 1: 無効なフラグ ‘-format’ // になる。
Maya2020で試した
// エラー: line 2: 有効なデフォーマが見つかりません。 //

なんだろ。

モデルがわるかった。スキンバインドが壊れてた。ジョイント曲げても反応なし

スキンウェイトに詳しくなりたい copySkinWeights コマンド

スキンウェイトに詳しくなりたい
スキンウェイトの世界は自動化がまだ追いついてないっぽい。
スキンウェイトのコピーの中身は

copySkinWeights -sourceSkin skinCluster1 -destinationSkin skinCluster2 -noMirror;
http://me.autodesk.jp/wam/maya/docs/Maya2010/Commands/copySkinWeights.html

cmds.copySkinWeights( sourceSkin=’skinCluster1′, destinationSkin=’skinCluster2′, noMirror=True
http://me.autodesk.jp/wam/maya/docs/Maya2010/CommandsPython/copySkinWeights.html

解決できないエラー(モデルがわるかった。スキンバインド全体が壊れてた。)
cmds.copySkinWeights( sourceSkin=’group_mesh|Mesh|Genesis8FemaleSkin’, destinationSkin=’group_meshHIK|Mesh|Genesis8FemaleSkin’, noMirror=True )

エラー: line 1: RuntimeError: file line 1: skinCluster ノードは -sourceSkin/-ss フラグとともに指定する必要があります。 #

解決できないエラー(一般的)(モデルがわるかった。スキンバインド全体が壊れてた。)
copySkinWeights -noMirror -surfaceAssociation closestPoint -influenceAssociation closestJoint;
// 警告: line 0: スキン オブジェクトではないので ‘Genesis8FemaleSkinShape’ をスキップします。 //
// エラー: line 0: 1 つのソース スキンと 1 つの目的のスキン、もしくはソースと目的のスキン上のコンポーネントを選択する必要があります。 //

ーーーーーーーーーーーーーーーーー
Maya2020でも解決できていない様子、(モデルがわるかった。スキンバインド全体が壊れてた。)

copySkinWeights -noMirror -surfaceAssociation closestPoint -influenceAssociation closestJoint;
// 警告: line 0: スキン オブジェクトではないので ‘Genesis8FemaleSkinShape’ をスキップします。 //
// エラー: line 0: 1 つのソース スキンと 1 つの目的のスキン、もしくはソースと目的のスキン上のコンポーネントを選択する必要があります。 //

cmds.copySkinWeights( sourceSkin=’group_mesh|Mesh|Genesis8FemaleSkin’, destinationSkin=’group_meshHIK|Mesh|Genesis8FemaleSkin’, noMirror=True )
エラー: RuntimeError: file line 1: skinCluster ノードは -sourceSkin/-ss フラグとともに指定する必要があります。 #

copySkinWeightsはそのコマンドの処理の中で、skinClusterコマンドを使っているみたいで
その引数部分にsourceSkinがうまくわたせてないみたいに見える。

モデルがわるかった。スキンバインド全体が壊れてた。


これも関係ありそう。
skinClusterは、一度に1つのジオメトリのみをバインドします。したがって、複数のジオメトリをバインドするには、複数のskinClusterコマンドを発行する必要があります。

https://help.autodesk.com/cloudhelp/2016/ENU/Maya-Tech-Docs/Commands/skinCluster.html

一旦1つの裸ジオメトリのスキンウェイトにしておいてそれを複数の服にコピーしていく流れをやったらいいのかもな。
ーーーーーーーーーーーーーーーーーーーーー

ダメだった。
cmds.copySkinWeights( sourceSkin=’group_mesh|Mesh|Genesis8FemaleSkin’, destinationSkin=’group_meshHIK|Mesh|Genesis8FemaleSkin’, noMirror=True )
エラー: line 1: RuntimeError: file line 1: skinCluster ノードは -sourceSkin/-ss フラグとともに指定する必要があります。 #

copySkinWeights -noMirror -surfaceAssociation closestPoint -influenceAssociation closestJoint;
// 警告: line 0: スキン オブジェクトではないので ‘Genesis8FemaleSkinShape’ をスキップします。 //
// エラー: line 0: 1 つのソース スキンと 1 つの目的のスキン、もしくはソースと目的のスキン上のコンポーネントを選択する必要があります。 //

Maya Selected Node All Childs node disconnectAttr Loop

選択したノード以下のすべての接続を解除するループ

import maya.cmds as cmds
selectionNode=cmds.ls(sl=True)
# 指定したノード以下全てを検索
selectionNodes=cmds.ls(selectionNode,dag=1)
for node in selectionNodes:
	try:
		attribute1 =node+"_translateX.output"
		attribute2 =node+".translateX"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass
	

	try:
		attribute1 =node+"_translateY.output"
		attribute2 =node+".translateY"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_translateZ.output"
		attribute2 =node+".translateZ"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_rotateX.output"
		attribute2 =node+".rotateX"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_rotateY.output"
		attribute2 =node+".rotateY"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_rotateZ.output"
		attribute2 =node+".rotateZ"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_scaleX.output"
		attribute2 =node+".scaleX"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_scaleY.output"
		attribute2 =node+".scaleY"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass

	try:
		attribute1 =node+"_scaleZ.output"
		attribute2 =node+".scaleZ"
		cmds.disconnectAttr(attribute1, attribute2)
	except RuntimeError as err:
		pass