2016年2月21日日曜日

フレーム毎に、選択したオブジェクトや頂点の場所へスフィアを配置するスクリプト

選択したオブジェクトや頂点の場所に、任意のフレーム分スフィアを配置します。
アニメーション作業で、フレーム間の動き幅や、動きがカーブを描いているのか、等の確認ように使いたいと思い作りました。
劣化版「Motion Trail」みたいなやつです。
選択したオブジェクトや頂点の位置情報をフレーム毎に取得しているので、キーが打たれていないものでもスフィアを配置できます。

[修正]2016/02/28 ver1.02
    2016/03/06 ver1.03
    2016/03/09 ver1.04

[注意]
※現状、シーン内に1つしか作ることができません。(グループ名とシェーダー名を固有で記述しているため)
※オブジェクトや頂点を複数選択している場合、動作しません。
※フレームは、小数点に対応していません。
※スフィアを作る時に、位置情報を取得するためにフレームが動きます。なのでシーンが重い場合、動作が遅くなります。
※ご使用の際は自己責任でお願いします。






●registration object

スフィアを配置したいオブジェクトや頂点を選択して、selectボタンを押してください。

●start frame
開始フレーム

●end frame
終了フレーム

●sphere scale
スフィアの大きさを変えます

●R、G、B
スフィアの色を変えます

●Transparency
スフィアの不透明度を変えます

●Ref
チェックを入れると、スフィアをオーバーライドしてReferenceにします

●Create
選択したオブジェクトや頂点の場所に「start frame」「end frame」で入力したフレーム分、スフィアを配置します。
既にスフィアがある状態で押すと、既存のスフィアを消して新しいスフィアを作ります。

●Delete
「Create」で作ったスフィアとグループ、マテリアルを消します


●スクリプト(python)
######################################################################
#    [内容]フレーム毎に選択したオブジェクトや頂点の場所にスフィアを置くスクリプト
#    複数選択には未対応
#    ver.1.04
#
#    Auther:Kyohei Ueno(heikyonoeu.blogspot.jp)
######################################################################

import maya.cmds as mc

###selectボタンを押したときに実行されるスクリプト###
def registrationObject():  
    #もし、何も選択されていなかったら、エラーメッセージを出す
    if not mc.ls(sl=1,fl=1):
        if mc.window('ErrorARONon',ex=1):
            mc.deleteUI('ErrorARONon')
         
        mc.window('ErrorARONon',title='Error',s=0)
        mc.columnLayout()
        mc.text(l='Nothing selected objects',w=200,h=50)
        mc.showWindow()
       
    #もし、現在選択されているオブジェクトが2つ以上なら、エラーメッセージを出す
    elif len(mc.ls(sl=1,fl=1)) >= 2:
        if mc.window('ErrorAROTwo',ex=1):
            mc.deleteUI('ErrorAROTwo')
         
        mc.window('ErrorAROTwo',title='Error',s=0)
        mc.columnLayout()
        mc.text(l='Too many selected objects',w=200,h=50)
        mc.showWindow()
       
    #スフィアを配置したいオブジェクトを登録
    else:
        regSel = mc.ls(sl=1)[0]
        mc.textFieldButtonGrp('regObject',edit=1,tx=regSel)

###Createボタンを押したときに実行されるスクリプト###
def createAnimRefObj(arg):
    global staF,endF,sphSiz,curSel,animRefCol_R_val,animRefCol_G_val,animRefCol_B_val,animRefTrp_val
       
    if mc.textFieldButtonGrp('regObject',q=1,tx=1) == '':
        if mc.window('ErrorARONon',ex=1):
            mc.deleteUI('ErrorARONon')
         
        mc.window('ErrorARONon',title='Error',s=0)
        mc.columnLayout()
        mc.text(l='Nothing selected objects',w=200,h=50)
        mc.showWindow()
   
    else:
        #もしsnimRef_gpがあったら、animRef_gp,animRef_lambert,animRef_lambertSGを消す
        if mc.objExists('animRef_gp'):
            mc.delete('animRef_gp')
            mc.delete('animRef_lambert')
            mc.delete('animRef_lambertSG')

        #現在選択されているオブジェクトを登録
        if mc.ls(sl=1):
            curSel = mc.ls(sl=1)[0]
       
        #Createボタンを押したフレームをcurFに入れる
        curF = mc.currentTime(q=1)
     
        #start frame,end frameに何も入力されていなかったら、エラーメッセージを出す
        try:
            staF = int(mc.textFieldGrp('startFrameRefField',q=1,text=1))
            endF = int(mc.textFieldGrp('endFrameRefField',q=1,text=1))
        except:
            if mc.window('ErrorAROFloat',ex=1):
                mc.deleteUI('ErrorAROFloat')

            mc.window('ErrorAROFloat',title='Error',s=0)
            mc.columnLayout()
            mc.text(l='Please frame number integer',w=200,h=50)
            mc.showWindow()
         
        allF = range(staF,endF+1)
     
        #スフィアのサイズ、R、G、B、不透明度をとってくる
        sphSiz = mc.floatSliderGrp('sphereSizeRefField',q=1,v=1)
        animRefCol_R_val = mc.floatSliderGrp('animRefCol_R_Field',q=1,v=1)
        animRefCol_G_val = mc.floatSliderGrp('animRefCol_G_Field',q=1,v=1)
        animRefCol_B_val = mc.floatSliderGrp('animRefCol_B_Field',q=1,v=1)
        animRefTrp_val = mc.floatSliderGrp('animRefTrp_Field',q=1,v=1)

        #registraion object欄のオブジェクトを登録
        regObj = mc.textFieldButtonGrp('regObject',q=1,tx=1)

        #animRef_gpという名のグループを作る
        mc.group(em=1,name='animRef_gp')
 
        #登録したオブジェクトの場所に、指定したフレーム分スフィアを作る
        for i in allF:
            mc.currentTime(i)
            curTra = mc.xform(regObj,q=1,ws=1,t=1)
            mc.polySphere(n='distance_sphere',sx=8,sy=8,r=1.0)
            mc.xform(ws=1,t=curTra,s=(sphSiz,sphSiz,sphSiz))
            aniRefSphere = mc.ls(sl=1)[0]
            mc.parent(aniRefSphere,'animRef_gp',r=1)

        #AnimRefObj用のlambertシェーダーを作って、animrRef_gpにアサインする
        animRef = mc.shadingNode('lambert',asShader=1,n='animRef_lambert')
        mc.hyperShade(animRef,a=1)
        mc.setAttr('animRef_lambert.colorR',animRefCol_R_val)
        mc.setAttr('animRef_lambert.colorG',animRefCol_G_val)
        mc.setAttr('animRef_lambert.colorB',animRefCol_B_val)
        mc.setAttr('animRef_lambert.transparency',animRefTrp_val,animRefTrp_val,animRefTrp_val)

        mc.select('animRef_gp')
        mc.hyperShade(assign = animRef)
     
        #Createボタンを押したフレームに戻る
        mc.currentTime(curF)
        #Createボタンを押した時に選択していたオブジェクトを選択
        mc.select(curSel)

###Deletボタンを押したときに実行されるスクリプト###
def deleteAnimRefObj(arg):
    if not mc.objExists('animRef_gp'):
        if mc.window('ErrorARODel',ex=1):
            mc.deleteUI('ErrorARODel')
        mc.window('ErrorARODel',title='Error',s=0)
        mc.columnLayout()
        mc.text(l='Nothing AnimRefObj objects',w=200,h=50)
        mc.showWindow()
     
    else:
        mc.delete('animRef_gp')
        mc.delete('animRef_lambert')
        mc.delete('animRef_lambertSG')
        mc.checkBox('animRef_RefCB',edit=1,v=0)

###start frame欄の値にファイルの最初のフレームを入れる###
def startFrameRef(arg):
    global staF
    staF = float(mc.textFieldGrp('startFrameRefField',q=1,text=1))

###end frame欄の値にファイルの最後のフレームを入れる###
def endFrameRef(arg):
    global endF
    endF = float(mc.textFieldGrp('endFrameRefField',q=1,text=1))
 
###sphere scale欄に入力されている値でスフィアをスケールする###
def sphereSizeRef(arg):
    global sphSiz
   
    if mc.ls(sl=1):
        curSel = mc.ls(sl=1)[0]
 
    sphSiz = float(mc.floatSliderGrp('sphereSizeRefField',q=1,v=1))
 
    if mc.objExists('animRef_gp'):
        mc.select('animRef_gp',hi=1)
        mc.select('animRef_gp',d=1)

        animeRefGpHi = mc.ls(sl=1)
        for i in animeRefGpHi:
            if mc.objectType(i) == 'transform':
                mc.xform(i,ws=1,s=(sphSiz,sphSiz,sphSiz))

    try:
        mc.select(curSel)
    except:
        mc.select(cl=1)

###スフィアのR値を変更する###
def animRefCol_R(arg):
    global animRefCol_R_val
    animRefCol_R_val = float(mc.floatSliderGrp('animRefCol_R_Field',q=1,v=1))

    if mc.objExists('animRef_gp'):
        mc.setAttr('animRef_lambert.colorR',animRefCol_R_val)
 
###スフィアのG値を変更する###
def animRefCol_G(arg):
    global animRefCol_G_val
    animRefCol_G_val = float(mc.floatSliderGrp('animRefCol_G_Field',q=1,v=1))

    if mc.objExists('animRef_gp'):
        mc.setAttr('animRef_lambert.colorG',animRefCol_G_val)

###スフィアのB値を変更する###
def animRefCol_B(arg):
    global animRefCol_B_val
    animRefCol_B_val = float(mc.floatSliderGrp('animRefCol_B_Field',q=1,v=1))
 
    if mc.objExists('animRef_gp'):
        mc.setAttr('animRef_lambert.colorB',animRefCol_B_val)
     
###スフィアの不透明度を変更する###
def animRefTrp(arg):
    global animRefTrp_val
    animRefTrp_val = float(mc.floatSliderGrp('animRefTrp_Field',q=1,v=1))
 
    if mc.objExists('animRef_gp'):
        mc.setAttr('animRef_lambert.transparency',animRefTrp_val,animRefTrp_val,animRefTrp_val)
     
###スフィアをオーバーライドでリファレンスにする###
def animRef_RefOn(arg):
    if mc.objExists('animRef_gp'):
        mc.setAttr('animRef_gp.overrideEnabled',1)
        mc.setAttr('animRef_gp.overrideDisplayType',2)
     
###スフィアのオーバーライドのリファレンスをとく###
def animRef_RefOff(arg):
    if mc.objExists('animRef_gp'):
        mc.setAttr('animRef_gp.overrideEnabled',0)
        mc.setAttr('animRef_gp.overrideDisplayType',0)

#window
if mc.window('animRefObj', ex=1):
    mc.deleteUI('animRefObj')
 
sceStaF = int(mc.playbackOptions(q=1,min=1))
sceEndF = int(mc.playbackOptions(q=1,max=1))
defSphSca = 1.0

mc.window('animRefObj',title='animRefObj',s=0)
mc.columnLayout()
mc.text(l='AnimRefObj Script')
mc.textFieldButtonGrp('regObject',l='registration object',bl='select',ed=0,cw3=(90,150,50),bc=registrationObject)
mc.textFieldGrp('startFrameRefField',l='start frame',tx=sceStaF,cw2=[90,60],cc=startFrameRef)
mc.textFieldGrp('endFrameRefField',l='end frame',tx=sceEndF,cw2=[90,60],cc=endFrameRef)
mc.floatSliderGrp('sphereSizeRefField',l='sphere scale',v=defSphSca,f=1,pre=3,cw3=(90,50,140),min=0.0,max=5.0,cc=sphereSizeRef)
mc.floatSliderGrp('animRefCol_R_Field',l='R',v=1.0,f=1,cw3=(90,50,100),min=0.0,max=1.0,cc=animRefCol_R)
mc.floatSliderGrp('animRefCol_G_Field',l='G',v=0,f=1,cw3=(90,50,100),min=0.0,max=1.0,cc=animRefCol_G)
mc.floatSliderGrp('animRefCol_B_Field',l='B',v=0,f=1,cw3=(90,50,100),min=0.0,max=1.0,cc=animRefCol_B)
mc.setParent('..')
mc.rowLayout(nc=2)
mc.floatSliderGrp('animRefTrp_Field',l='Transparency',v=0,f=1,cw3=(90,50,50),min=0.0,max=1.0,cc=animRefTrp)
mc.checkBox('animRef_RefCB',l='Ref',onc=animRef_RefOn,ofc=animRef_RefOff,v=0)
mc.setParent('..')
mc.rowLayout(nc=2)
mc.button(l='Create',c=createAnimRefObj,w=110,bgc=(1,0.443,0))
mc.button(l='Delete',c=deleteAnimRefObj,w=110,bgc=(0.8,0.8,0.8))
mc.showWindow()