pythonの標準モジュールで windowsにクリップボードにコピーするには?

pyperclipを使わないで、pythonの標準モジュールで windowsにクリップボードにコピーするには?

import subprocess 
s="abcdefg"
print("s=__"+s+"__")
subprocess.run("clip", text=True, input=s)

参考

Python script to copy text to clipboard [duplicate]

https://stackoverflow.com/questions/11063458/python-script-to-copy-text-to-clipboard

[clip / pbcopy・pbpaste]クリップボードにコピー

https://xtech.nikkei.com/it/atcl/column/15/042000103/080400036/

[unrealEngine,Maya]で腕や足がスカートを貫通しないようにしたい

あくまで、自分の研究例ですと
スカートで足に追従させたいものは
「膝にスキニングしたほうが作業的に効率的」です。
ジャンプや走るモーションで
前側のスカートは膝で突き破るので、
膝にスキンウェイト当てておきます。
というより

タイトスカートのスキンウェイトは、まず足にスキンウェイトを足の一部のようにスキンウェイトをコピーします。
前側の又の部分は左右の足から同じ左0.5、右0.5になるようにスキンウェイトします。
ロングタイトスカートはこれでできます。

スカートのケージモデルが膝に追従する例です。
ただ、まだ、突き破っているので、スカートモデルと体の隙間をもっと大きくした方がいいでしょう


あとは物理で動かしたい頂点は下のようにします
さらに、フレアスカートの場合は
スカートの左右と後ろ部分は、放射状にジョイントをいれヒザのスキンウェイトとグラデーションするようにスキンウェイトします。あとは、おかずさんのkawaii physics で、マニュアル通り設定します。

関連

AmbitionEarlyHourSky

#アンリアルクエスト に出したゲームのクオリティをアップした。

キャラクターの作り直しを何度もやった。

ハイヒールのカラーをルブタンみたいにして

ニーアみたいなマスクをつけて
kawaiiphysicsでスカートをひらひらさせた。
kawaiiphysicsで胸も揺らした
kawaiiphysicsで髪をなびくようにジョイントを入れ

レベルデザインも少しちゃんとした。

#kawaiiphysics #UE4 #Unrealお兄さん と#塩谷さん と #おかず さん の おかげです。

ダウンロードはこちら

https://drive.google.com/file/d/1q6O0NIBkd-oH1zD50XCDv74sUi6QfIai/view?usp=sharing

最近開いてみたらこんなエラーが出た

This Project requires the ‘ShallowWater’ plugin whitch could not be found.Would you like to desable it continue?If you do you will no longer be able to open any assets created with it. if not the application will close.

このプロジェクトには、見つからなかった「ShallowWater」プラグインが必要です。引き続き無効にしますか?そうすると、それで作成されたアセットを開くことができなくなります。 そうでない場合、アプリケーションは終了します。

ビルドの必要がありそうなので

A案

cd C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles
Build.bat AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket

B案

cd C:\Program Files\Epic Games\UE_5.0\Engine\Binaries\DotNET\UnrealBuildTool
UnrealBuildTool.exe AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket

ERROR: Unable to find plugin ‘ShallowWater’ (referenced via AmbitionEarlyHourSky.uproject). Install it and try again, or remove it from the required plugin list.

と言われるので。

AmbitionEarlyHourSky.uprojectの Plugin から ShallowWaterを消す。

{
	"FileVersion": 3,
	"EngineAssociation": "5.0",
	"Category": "",
	"Description": "",
	"Modules": [
		{
			"Name": "AmbitionEarlyHourSky",
			"Type": "Runtime",
			"LoadingPhase": "Default",
			"AdditionalDependencies": [
				"Engine"
			]
		}
	],
	"Plugins": [
		{
			"Name": "ShallowWater",
			"Enabled": true
		},
		{
			"Name": "Water",
			"Enabled": true
		},
		{
			"Name": "PythonScriptPlugin",
			"Enabled": true
		},
		{
			"Name": "EditorScriptingUtilities",
			"Enabled": true
		},
		{
			"Name": "Bridge",
			"Enabled": true,
			"SupportedTargetPlatforms": [
				"Win64",
				"Mac",
				"Linux"
			]
		}
	]
}

Build.batできたっぽい


C:\Users\furcr>cd C:\Program Files\Epic Games\UE_5.0\Engine\Binaries\Win64\

C:\Program Files\Epic Games\UE_5.0\Engine\Binaries\Win64>cd ../../

C:\Program Files\Epic Games\UE_5.0\Engine>cd C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles

C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles>Build.bat AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket
Using bundled DotNet SDK
Log file: C:\Users\furcr\AppData\Local\UnrealBuildTool\Log.txt
Creating makefile for AmbitionEarlyHourSky (Build.version is newer)
ERROR: Unable to find plugin 'ShallowWater' (referenced via AmbitionEarlyHourSky.uproject). Install it and try again, or remove it from the required plugin list.

C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles>Build.bat AmbitionEarlyHourSky Win64 Development "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" -rocket
Using bundled DotNet SDK
Log file: C:\Users\furcr\AppData\Local\UnrealBuildTool\Log.txt
Creating makefile for AmbitionEarlyHourSky (Build.version is newer)
Parsing headers for AmbitionEarlyHourSky
  Running UnrealHeaderTool "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\AmbitionEarlyHourSky.uproject" "F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\Intermediate\Build\Win64\AmbitionEarlyHourSky\Development\AmbitionEarlyHourSky.uhtmanifest" -LogCmds="loginit warning, logexit warning, logdatabase error" -Unattended -WarningsAsErrors -abslog="C:\Users\furcr\AppData\Local\UnrealBuildTool\Log_UHT.txt" -installed
Reflection code generated for AmbitionEarlyHourSky in 6.3933034 seconds
Building AmbitionEarlyHourSky...
Using Visual Studio 2019 14.29.30141 toolchain (C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133) and Windows 10.0.18362.0 SDK (C:\Program Files (x86)\Windows Kits\10).
[Adaptive Build] Excluded from AmbitionEarlyHourSky unity file: MyBlueprintFunctionLibrary.cpp, SaveToText.cpp, TextFileToString.cpp, AmbitionEarlyHourSky.cpp, AmbitionEarlyHourSkyCharacter.cpp, AmbitionEarlyHourSkyGameMode.cpp
Distributing 23 actions to XGE
--------------------Build System Warning---------------------------------------
License is invalid:
    License information is invalid. Please try reloading your license file using the Coordinator Monitor application on the Coordinator machine, or reinstall IncrediBuild.
    This build will run in standalone mode.

-------------------------------------------------------------------------------

Build ID: {5E64F7BF-47B0-4AF8-8F9B-4464A50705EC}

--------------------Project: Default-------------------------------------------
[1/23] SharedPCH.Engine.ShadowErrors.cpp (0:51.37 at +0:00)
[2/23] OpenImageDenoise.dll (0:00.64 at +0:51)
[3/23] tbb.dll (0:00.26 at +0:52)
[4/23] d3d12SDKLayers.dll (0:00.31 at +0:52)
[5/23] D3D12Core.dll (0:00.28 at +0:52)
[6/23] tbb12.dll (0:00.31 at +0:52)
[7/23] AmbitionEarlyHourSkyCharacter.cpp (0:01.64 at +0:53)
[8/23] AmbitionEarlyHourSkyGameMode.cpp (0:01.01 at +0:54)
[9/23] SaveToText.cpp (0:00.60 at +0:55)
[10/23] MyBlueprintFunctionLibrary.gen.cpp (0:00.62 at +0:56)
[11/23] AmbitionEarlyHourSkyCharacter.gen.cpp (0:00.92 at +0:57)
[12/23] MyBlueprintFunctionLibrary.cpp (0:00.57 at +0:58)
[13/23] TextFileToString.gen.cpp (0:00.62 at +0:58)
[14/23] AmbitionEarlyHourSky.cpp (0:00.70 at +0:59)
[15/23] AmbitionEarlyHourSky.init.gen.cpp (0:00.64 at +1:00)
[16/23] TextFileToString.cpp (0:15.11 at +1:00)
[17/23] AmbitionEarlyHourSkyGameMode.gen.cpp (0:01.00 at +1:15)
[18/23] Default.rc2 (0:00.48 at +1:16)
[19/23] Module.KawaiiPhysics.cpp (0:03.53 at +1:17)
[20/23] Module.KawaiiPhysics.gen.cpp (0:03.40 at +1:20)
[21/23] SaveToText.gen.cpp (0:00.65 at +1:24)
[22/23] AmbitionEarlyHourSky.exe (0:26.03 at +1:24)
   Creating library F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\Binaries\Win64\AmbitionEarlyHourSky.lib and object F:\Download\Game\AmbitionEarlyHourSky6.0NoCascade\Binaries\Win64\AmbitionEarlyHourSky.exp
[23/23] AmbitionEarlyHourSky.target (0:00.34 at +1:50)
---------------------- Done ----------------------

    Rebuild All: 1 succeeded, 0 failed, 0 skipped

1 build system warning(s):
   - License is invalid

Total time in XGE executor: 111.50 seconds
Total execution time: 128.20 seconds

C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles>

リビルドするか聞かれる。リビルドで、30秒後ぐらいに起動した!

スカートのリグなどを頑張ったオリジナル作品のAmbitionSkyWaterをUE5でビルドしなおして、ポスプロなどブラッシュアップして動画を取り直した #UE5 #UnrealEngine5 #スカート #リグ #Rig #skirts

[maya] mel get all material

全然検索してもでてこないのに簡単だった。

NO MEAN    
  string $shadingEngines[]=`ls -type "shadingEngine"`;
    //string $materials[]=`ls -type "material"`;
    string $ShaderS[];
    string $lambertS[]=`ls -type "lambert"`;
    string $phongS[]=`ls -type "phong"`;
    string $materials[]=`ls -sl`;

shadingEnginesとか関係なかった。

//ANSWER
string $allMaterials[] = `ls -materials`;

    for($mtl in $allMaterials)
    {
      string $materialsType=`objectType $mtl`;
      print("$mtl= "+$mtl+" $materialsType="+$materialsType+"\n");
    }

[maya]AnimCurveへの掛け算、足し算

掛け算は scaleKey の valueScale を使う

from maya import cmds 
import pymel.core as pm 

# translate
obj="sphere1"
trans1=".tx"
                    pm.scaleKey([str(obj) + trans1],
                     valuePivot=0, timeScale=1, 
                     hierarchy='none', 
                     float=(min,max), 
                     floatPivot=0, valueScale=-1, 
                     timePivot=0, scaleSpecifiedKeys=1, 
                     shape=1, time=(min,max), 
                     floatScale=1, controlPoints=0)

#rotation
pm.scaleKey([str(obj) + rot2], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)

足し算は pm.pasteKey の valueOffset を使う

#min max
    animCurve_Arr = cmds.ls( type="animCurve" );
    print("animCurve_Arr= "+str(animCurve_Arr))
    min=0
    max=0
    for animCurve in animCurve_Arr:
        newMin = cmds.findKeyframe(animCurve,which="first")
        newMax = cmds.findKeyframe(animCurve,which="last")
        #print("newMin= "+str(newMin))
        #print("newMax= "+str(newMax))
        if(newMin<min):    
            min=newMin
            
        if(newMax>max):
            max=newMax
                
    print("min= "+str(min))
    print("max= "+str(max))

#rotaion
pm.copyKey((obj + rot1), hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
pm.cutKey((obj + rot1), f=(min,max), t=(min,max), cl=1)
pm.pasteKey((obj + rot1), floatOffset=0, option='replace', copies=1, valueOffset=180, connect=1, timeOffset=0)
         
               

以下は Maya2022 >Bonus Tools >Animation >Mirror Animation のmelを

をPythonに変換したもの

例 モーションのアニムカーブのミラーのサンプル


def bt_applyMirrorAnim(axis, method, xforms, ignore, custom):
    
    trans = ""
    rot1 = ""
    rot2 = ""
    connection = []
    lockCheck1 = []
    lockCheck2 = []
    attrListOrig = []
    attrListFinal = []
    objList=cmds.ls(allPaths=1,long=1, selection=1)
    print("objList= "+str(objList))
    attrCount=0
    if xforms[0]==1:
        #attrListOrig[attrCount]=".tx"
        attrListOrig.append(".tx")
        attrCount+=1
        #attrListOrig[attrCount]=".ty"
        attrListOrig.append(".ty")
        attrCount+=1
        #attrListOrig[attrCount]=".tz"
        attrListOrig.append(".tz")
        attrCount+=1
        
    if xforms[1]==1:
        #attrListOrig[attrCount]=".rx"
        attrListOrig.append(".rx")
        attrCount+=1
        #attrListOrig[attrCount]=".ry"
        attrListOrig.append(".ry")
        attrCount+=1
        #attrListOrig[attrCount]=".rz"
        attrListOrig.append(".rz")
        attrCount+=1
        
    if xforms[2]==1:
        #attrListOrig[attrCount]=".sx"
        attrListOrig.append(".sx")
        attrCount+=1
        #attrListOrig[attrCount]=".sy"
        attrListOrig.append(".sy")
        attrCount+=1
        #attrListOrig[attrCount]=".sz"
        attrListOrig.append(".sz")
        attrCount+=1
        
    if (custom == 1) and (len(objList) == 2):
        userAttrList=pm.listAttr(objList[0], userDefined=1)
        #Look for custom attrs on first object
        for uAttr in userAttrList:
            if pm.mel.attributeExists(uAttr, objList[1]):
                #attrListOrig[attrCount]=("." + str(uAttr))
                attrListOrig.append("." + str(uAttr))
                #Check for same attr on second
                attrCount+=1

            
        
    if axis == 1:
        trans=".tx"
        rot1=".ry"
        rot2=".rz"
        
    
    elif axis == 2:
        trans=".ty"
        rot1=".rx"
        rot2=".rz"
        
    
    elif axis == 3:
        trans=".tz"
        rot1=".rx"
        rot2=".ry"
        
    elif axis == 4:
        trans=".ty"
        rot1=".ry"
        rot2=".rz"

    elif axis == 5:
        trans1=".tx"
        trans2=".ty"
        trans3=".tz"
        rot3=".rz"

    elif axis == 6:
        trans=".tx"
        trans1=".tx"
        trans2=".ty"
        trans3=".tz"
        rot1=".rx"
        rot2=".ry"
        rot3=".rz"

    animCurve_Arr = cmds.ls( type="animCurve" );
    print("animCurve_Arr= "+str(animCurve_Arr))
    min=0
    max=0
    for animCurve in animCurve_Arr:
        newMin = cmds.findKeyframe(animCurve,which="first")
        newMax = cmds.findKeyframe(animCurve,which="last")
        #print("newMin= "+str(newMin))
        #print("newMax= "+str(newMax))
        if(newMin<min):    
            min=newMin
            
        if(newMax>max):
            max=newMax
                
    print("min= "+str(min))
    print("max= "+str(max))

    """
    if (custom == 1) and (method == 5):
        # 接続を解除
        for obj in objList:
            deleteConnection(obj+".tx")
            deleteConnection(obj+".ty")
            deleteConnection(obj+".tz")
            deleteConnection(obj+".rx")
            deleteConnection(obj+".ry")
            deleteConnection(obj+".rz")
    """       
    if method == 4:
        print("method= 4   minus Mode...")
        if len(objList) != 2:
            print("Not 2 selected")
        
        """
        elif axis == 4:
        trans=".ty"
        rot1=".ry"
        rot2=".rz"

        """
        for obj in objList:
            print("obj= "+str(obj))
            if xforms[0]:
                lockCheck1=pm.listAttr((str(obj) + trans), l=1)
                
                # invert appropriate attrs and/or curves for objects
                #Translate
                if len(lockCheck1) == 0:
                    print("trans= "+str(trans))
                    #print(u"Inverting static value and/or animation for " + str(obj) + trans + "")
                    AttValue=pm.getAttr(str(obj) + trans)
                    print("AttValue= "+str(AttValue))
                    pm.setAttr((str(obj) + trans), (AttValue * -1))
                    #pm.setAttr((str(obj) + trans), (AttValue ))
                    pm.scaleKey([str(obj) + trans],
                     valuePivot=0, timeScale=1, 
                     hierarchy='none', 
                     float=(min,max), 
                     floatPivot=0, valueScale=-1, 
                     timePivot=0, scaleSpecifiedKeys=1, 
                     shape=1, time=(min,max), 
                     floatScale=1, controlPoints=0)
                    
                  
            if xforms[1]:
                animCurve_rot1=cmds.listConnections((str(obj) + rot1), t="animCurve")
                print("animCurve_rot1="+str(animCurve_rot1))
                lockCheck1=pm.listAttr((str(obj) + rot1), l=1)
                #Rotate
                if len(lockCheck1) == 0:
                    print("rot1= "+str(rot1))
                    print(u"Inverting static values and/or animation for " + str(obj) + rot1 + "")
                    
                    #pm.setAttr((str(obj) + rot1), (pm.getAttr(str(obj) + rot1) ))
                    #cmds.keyframe((str(obj) + rot1),e=True, time=(), r=True, vc=180)
                    """
                    pm.scaleKey([str(obj) + rot1], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=+180, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                    """
                    
                connection=pm.listConnections((obj + rot1), s=True, d=False)
                if(len(connection)>0):
                    if pm.mel.isAnimCurve(connection[0]):
                        print("obj= "+obj + " rot1= "+rot1)
                        pm.copyKey((obj + rot1), 
                            hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                        pm.cutKey((obj + rot1), 
                            f=(min,max), t=(min,max), cl=1)
                        pm.pasteKey((obj + rot1), 
                            floatOffset=0, option='replace', copies=1, valueOffset=180, connect=1, timeOffset=0)
                        
                   
                    else:
                        val=pm.getAttr(obj + rot3)
                        pm.setAttr((obj + rot3),  val+180)
                    
                    
                    
                animCurve_rot2=cmds.listConnections((str(obj) + rot2), t="animCurve")
                print("animCurve_rot2="+str(animCurve_rot2))     
                lockCheck1=pm.listAttr((str(obj) + rot2), l=1)
                if len(lockCheck1) == 0:
                    print("rot2= "+str(rot2))
                    print(u"Inverting static values and/or animation for " + str(obj) + rot2 + "")
                    pm.setAttr((str(obj) + rot2), (pm.getAttr(str(obj) + rot2) * -1))
                    pm.scaleKey([str(obj) + rot2], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                    
                    
    elif method == 2:
        print("method=2   minus Mode...")
        if len(objList) != 2:
            print("Not 2 selected ")
        

        for obj in objList:
            print("obj= "+str(obj))
            if xforms[0]:
                lockCheck1=pm.listAttr((str(obj) + trans), l=1)
                
                # invert appropriate attrs and/or curves for objects
                #Translate
                if len(lockCheck1) == 0:
                    print("trans")
                    #print(u"Inverting static value and/or animation for " + str(obj) + trans + "")
                    AttValue=pm.getAttr(str(obj) + trans)
                    print("AttValue= "+str(AttValue))
                    pm.setAttr((str(obj) + trans), (AttValue * -1))
                    pm.scaleKey([str(obj) + trans], 
                    valuePivot=0, timeScale=1, 
                    hierarchy='none', float=(min,max), 
                    floatPivot=0, valueScale=-1, timePivot=0, 
                    scaleSpecifiedKeys=1, shape=1, 
                    time=(min,max), floatScale=1, 
                    controlPoints=0)
                    
                  
            if xforms[1]:
                lockCheck1=pm.listAttr((str(obj) + rot1), l=1)
                #Rotate
                if len(lockCheck1) == 0:
                    print("rot1")
                    print(u"Inverting static values and/or animation for " + str(obj) + rot1 + "")
                    pm.setAttr((str(obj) + rot1), (pm.getAttr(str(obj) + rot1) * -1))
                    pm.scaleKey([str(obj) + rot1], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                     
                lockCheck1=pm.listAttr((str(obj) + rot2), l=1)
                if len(lockCheck1) == 0:
                    print("rot2")
                    print(u"Inverting static values and/or animation for " + str(obj) + rot2 + "")
                    pm.setAttr((str(obj) + rot2), (pm.getAttr(str(obj) + rot2) * -1))
                    pm.scaleKey([str(obj) + rot2], 
                        valuePivot=0, 
                        timeScale=1, 
                        hierarchy='none', 
                        float=(min,max), 
                        floatPivot=0, valueScale=-1, 
                        timePivot=0, scaleSpecifiedKeys=1, 
                        shape=1, 
                        time=(min,max), 
                        floatScale=1, controlPoints=0)
                    
                
            

    elif (method == 1) and (len(objList) == 2):
        print("method 1  base  No minus Mode...")
        print("elif (method == 1) and (len(objList) == 2)")
        
        first=objList[0]
        second=objList[1]
        print("first= "+str(first))
        print("second= "+str(second))
        print(u"Mirroring static values and animation for " + trans + ", " + rot1 + " and " + rot2 + " animation for " + str(first) + " and " + str(second) + "")
        #Check attrs for editability
        count=0
        for attr in attrListOrig:
            lockCheck1=pm.listAttr((first + attr), 
                l=1)
            lockCheck2=pm.listAttr((second + attr), 
                l=1)
            if (len(lockCheck1) != 0) and (ignore == 1):
                print("Ignoring " + str(first) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck1) != 0) and (ignore == 0):
                print("Aborting : " + str(first) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            elif (len(lockCheck2) != 0) and (ignore == 1):
                print("Ignoring " + str(second) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck2) != 0) and (ignore == 0):
                print("Aborting : " + str(second) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            else:
                #attrListFinal[count]=str(attr)
                attrListFinal.append(str(attr))
                count+=1
                
           
        cmds.select(first, r=1)
        #pm.mel.duplicatePreset(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1)
        cmds.duplicate(returnRootsOnly=1)
        dup=cmds.ls(sl=True)
        tmpObj=cmds.rename(dup[0], 'tmp_transfer_obj')
        for attr in attrListFinal:
            connection=pm.listConnections((first + attr), s=True, d=False)
            #print("connection= "+str(connection) )
            
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    #animCurve_Arr = cmds.ls( type="animCurve" );
                    #print("connection[0]= "+str(connection[0]) )
                    #newMin = cmds.findKeyframe(connection[0],which="first")
                    #newMax = cmds.findKeyframe(connection[0],which="last")
                    print("first= "+first + " attr= "+attr)
                    pm.copyKey((first + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
             
                        
                    pm.cutKey((tmpObj + attr),f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((tmpObj + attr),floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                      
                
                else:
                    val=pm.getAttr(first + attr)
                    pm.setAttr((tmpObj + attr),  val)
        
            
        for attr in attrListFinal:
            connection=pm.listConnections((second + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("second= "+second + " attr= "+attr)
                    pm.copyKey((second + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((first + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((first + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
               
                else:
                    val=pm.getAttr(second + attr)
                    pm.setAttr((first + attr),  val)
                
       
        for attr in attrListFinal:
            connection=pm.listConnections((tmpObj + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("tmpObj= "+tmpObj + " attr= "+attr)
                    pm.copyKey((tmpObj + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((second + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((second + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
                
                else:
                    val=pm.getAttr(tmpObj + attr)
                    pm.setAttr((second + attr),  val)
                
    
        if xforms[0]:
            lockCheck1=pm.listAttr((str(first) + trans), 
                l=1)
            #if translate is on
            if len(lockCheck1) == 0:
                print("first= "+first + " trans= "+trans)
                #pm.setAttr((str(first) + trans), (pm.getAttr(str(first) + trans) * -1))
                pm.setAttr((str(first) + trans), (pm.getAttr(str(first) + trans) ))
                pm.scaleKey([str(first) + trans], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(second) + trans), 
                l=1)
            if len(lockCheck1) == 0:
                print("second= "+second + " trans= "+trans)
                #pm.setAttr((str(second) + trans), (pm.getAttr(str(second) + trans) * -1))
                pm.setAttr((str(second) + trans), (pm.getAttr(str(second) + trans) ))
                pm.scaleKey([str(second) + trans], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            
        if xforms[1]:
            lockCheck1=pm.listAttr((str(first) + rot1), 
                l=1)
            #if rotate is on
            if len(lockCheck1) == 0:
                print("first= "+first + " rot1= "+rot1)
                #pm.setAttr((str(first) + rot1), (pm.getAttr(str(first) + rot1) * -1))
                pm.setAttr((str(first) + rot1), (pm.getAttr(str(first) + rot1) ))
                pm.scaleKey([str(first) + rot1], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(first) + rot2), 
                l=1)
            if len(lockCheck1) == 0:
                print("first= "+first + " rot2= "+rot2)
                #pm.setAttr((str(first) + rot2), (pm.getAttr(str(first) + rot2) * -1))
                pm.setAttr((str(first) + rot2), (pm.getAttr(str(first) + rot2) ))
                pm.scaleKey([str(first) + rot2], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(second) + rot1), 
                l=1)
            if len(lockCheck1) == 0:
                print("second= "+second + " rot1= "+rot1)
                #pm.setAttr((str(second) + rot1), (pm.getAttr(str(second) + rot1) * -1))
                pm.setAttr((str(second) + rot1), (pm.getAttr(str(second) + rot1) ))
                pm.scaleKey([str(second) + rot1], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            lockCheck1=pm.listAttr((str(second) + rot2), 
                l=1)
            if len(lockCheck1) == 0:
                print("second= "+second + " rot2= "+rot2)
                #pm.setAttr((str(second) + rot2), (pm.getAttr(str(second) + rot2) * -1))
                pm.setAttr((str(second) + rot2), (pm.getAttr(str(second) + rot2) ))
                pm.scaleKey([str(second) + rot2], 
                    scaleSpecifiedKeys=1, valuePivot=0, valueScale=1)
                
            
        pm.delete(tmpObj)
        cmds.select(objList, r=1)
        # Reset frame to current time so that changes are visually updated
        t=cmds.currentTime(query=1)
        cmds.currentTime(t, e=1)

    elif (method == 3) and (len(objList) == 2):
        print("equip_LR_mode------------------------------------------------")
        print("elif (method == 3)")
        
        first=objList[0]
        second=objList[1]
        print("first= "+str(first))
        print("second= "+str(second))
        print(u"Mirroring static values and animation for " + trans + ", " + rot1 + " and " + rot2 + " animation for " + str(first) + " and " + str(second) + "")
        #Check attrs for editability
        count=0
        for attr in attrListOrig:
            print("first= "+str(first)+" attr1= " +str(attr))
            lockCheck1=pm.listAttr((first + attr), 
                l=1)
            lockCheck2=pm.listAttr((second + attr), 
                l=1)
            if (len(lockCheck1) != 0) and (ignore == 1):
                print("Ignoring " + str(first) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck1) != 0) and (ignore == 0):
                print("Aborting : " + str(first) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            elif (len(lockCheck2) != 0) and (ignore == 1):
                print("Ignoring " + str(second) + str(attr) + " because it is locked.")
                continue
                
            
            elif (len(lockCheck2) != 0) and (ignore == 0):
                print("Aborting : " + str(second) + str(attr) + " is locked.  Either unlock attributes or turn on IgnoreLockedAttributs in mirror options")
                
            
            else:
                #attrListFinal[count]=str(attr)
                attrListFinal.append(str(attr))
                count+=1
                
           
        cmds.select(first, r=1)
        #pm.mel.duplicatePreset(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1)
        cmds.duplicate(returnRootsOnly=1)
        dup=cmds.ls(sl=True)
        tmpObj=cmds.rename(dup[0], 'tmp_transfer_obj')
        for attr in attrListFinal:
            connection=pm.listConnections((first + attr), s=True, d=False)
            #print("connection= "+str(connection) )
            
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    #animCurve_Arr = cmds.ls( type="animCurve" );
                    #print("connection[0]= "+str(connection[0]) )
                    #newMin = cmds.findKeyframe(connection[0],which="first")
                    #newMax = cmds.findKeyframe(connection[0],which="last")
                    print("tmp_transfer_obj  pasteKey first= "+str(first)+" attr1= " +str(attr))
                    pm.copyKey((first + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
             
                        
                    pm.cutKey((tmpObj + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((tmpObj + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                      
                
                else:
                    val=pm.getAttr(first + attr)
                    pm.setAttr((tmpObj + attr),  val)
        
            
        for attr in attrListFinal:
            connection=pm.listConnections((second + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("tmp_transfer_obj  pasteKey attr2= " +str(attr))
                    pm.copyKey((second + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((first + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((first + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
               
                else:
                    val=pm.getAttr(second + attr)
                    pm.setAttr((first + attr),  val)
                
       
        for attr in attrListFinal:
            connection=pm.listConnections((tmpObj + attr), s=True, d=False)
            if(len(connection)>0):
                if pm.mel.isAnimCurve(connection[0]):
                    print("tmp_transfer_obj  pasteKey attr3= " +str(attr))
                    pm.copyKey((tmpObj + attr), 
                        hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                    pm.cutKey((second + attr), 
                        f=(min,max), t=(min,max), cl=1)
                    pm.pasteKey((second + attr), 
                        floatOffset=0, option='replace', copies=1, valueOffset=0, connect=1, timeOffset=0)
                    
                
                else:
                    val=pm.getAttr(tmpObj + attr)
                    pm.setAttr((second + attr),  val)
                
    
        if xforms[0]:
            lockCheck1=pm.listAttr((str(first) + trans), l=1)
            #if translate is on
            if len(lockCheck1) == 0:
                print("else tx   first"+str(first)+" trans1= " +str(trans1))
                pm.setAttr((str(first) + trans1), (pm.getAttr(str(first) + trans1) * -1))
                pm.scaleKey([str(first) + trans1],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else ty   first"+str(first)+" trans2= " +str(trans2))
                pm.setAttr((str(first) + trans2), (pm.getAttr(str(first) + trans2) * -1))
                pm.scaleKey([str(first) + trans2],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else tz   first"+str(first)+" trans3= " +str(trans3))
                pm.setAttr((str(first) + trans3), (pm.getAttr(str(first) + trans3) * -1))
                pm.scaleKey([str(first) + trans3],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                
                print("else tx   second"+str(second)+" trans1= " +str(trans1))
                pm.setAttr((str(second) + trans1), (pm.getAttr(str(second) + trans1) * -1))
                pm.scaleKey([str(second) + trans1],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else ty   second"+str(second)+" trans2= " +str(trans2))
                pm.setAttr((str(second) + trans2), (pm.getAttr(str(second) + trans2) * -1))
                pm.scaleKey([str(second) + trans2],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
                print("else tz   second"+str(second)+" trans3= " +str(trans3))
                pm.setAttr((str(second) + trans3), (pm.getAttr(str(second) + trans3) * -1))
                pm.scaleKey([str(second) + trans3],scaleSpecifiedKeys=1, valuePivot=0, valueScale=-1)
    
        """    
        if xforms[1]:
            lockCheck1=pm.listAttr((str(first) + rot3), 
            if len(lockCheck1) == 0:
                print("------")
                connection=pm.listConnections((obj + rot1), s=True, d=False)
                if(len(connection)>0):
                    if pm.mel.isAnimCurve(connection[0]):
                        print("obj= "+obj + " rot1= "+rot1)
                        pm.copyKey((obj + rot1), 
                            hierarchy='none', shape=1, float=(min,max), controlPoints=0, time=(min,max))
                        pm.cutKey((obj + rot1), 
                            f=(min,max), t=(min,max), cl=1)
                        pm.pasteKey((obj + rot1), 
                            floatOffset=0, option='replace', copies=1, valueOffset=180, connect=1, timeOffset=0)
                        
                   
                    else:
                        val=pm.getAttr(obj + rot3)
                        pm.setAttr((obj + rot3),  val+180)
                print("------")
        """
        pm.delete(tmpObj)
        cmds.select(objList, r=1)
        # Reset frame to current time so that changes are visually updated
        t=cmds.currentTime(query=1)
        cmds.currentTime(t, e=1)

        

        
    elif (method == 1) and (len(objList) != 2):
        print("Wrong number of objects.  Select 2 transfroms to mirror between")
        
#example
bt_applyMirrorAnim(2, 2, [1,1,0], 1, 1) 
bt_applyMirrorAnim(4, 4, [1,1,0], 1, 1)
bt_applyMirrorAnim(5, 3, [1,1,0], 1, 1)
bt_applyMirrorAnim(2, 2, [1,1,0], 1, 1) 

参考

Maya AnimCurve のデータを Pythonで取得するメモ

https://qiita.com/syoyo/items/376541f60e7cdb346399

[UnrealEngine] Export TGA by Python

import unreal

import codecs
import os
def my_makedirs(path):
    if not os.path.isdir(path):
        os.makedirs(path)

my_makedirs(SaveDir)
print("SaveDir= "+SaveDir)
print("FileName= "+FileName)
savePath=SaveDir+"/"+FileName+".tga"
print("savePath= "+savePath)



editorAssetLib = unreal.EditorAssetLibrary()
texture2d=editorAssetLib.load_asset(assetPath) 
#canvasRenderTarget2D=editorAssetLib.load_asset(assetPath) 
#texture2d=unreal.Texture2D(canvasRenderTarget2D)
print("texture2d= "+str(texture2d))

task = unreal.AssetExportTask()
task.set_editor_property('automated', True)
task.set_editor_property('filename', savePath)
task.set_editor_property('object', texture2d)
task.set_editor_property('prompt', False)
task.set_editor_property('exporter', unreal.TextureExporterTGA())

check = unreal.Exporter.run_asset_export_task(task)


if check==True:
    pass
else:
    print(u"tga イメージの生成に失敗しました")

[maya]「スムーズ スキン サーフェスから未使用のインフルエンスを除去する」だけで、すごくいろんな動作が軽くなる。

Maya の処理スピードを向上させスキン ウェイト ペイント ツール(Paint Skin Weights Tool)を使いやすくするために、全てのスキン ウェイトが 0 であるスムーズ スキンから、ジョイントとインフルエンス オブジェクトを接続解除することができます。これにより未使用のインフルエンスがスキンのインフルエンス(Influence)リストに表示されなくなり、スキン ウェイト ペイント ツール(Paint Skin Weights Tool)が使いやすくなります。

たとえば、既定のオプションを使って、人間のスケルトンにストッキングをはいた左足をスムーズ スキニングするとします。スケルトン内のすべてのジョイントがポテンシャル インフルエンスとしてストッキングに接続されますが、ウェイトが 0 以外の値になるのは左足のストッキングに最も近いジョイントだけです。

肘を選択して回転させると、Maya はストッキングのスキンを計算して 0 以外の値をもつウェイトがないかどうかを調べます。ストッキングを未使用のインフルエンスから接続解除すると、肘とウェイトが 0 のその他のジョイントの回転を処理する必要がなくなり、パフォーマンスが向上します。

未使用のインフルエンスを除去するには

  1. スキンを選択します。
  2. スキン > 影響を編集 > 使われていないインフルエンスの除去(Skin > Edit Influences > Remove Unused Influences)を選択します。

[maya] pymel.tools.mel2py の python3版 変換できない問題がある20220926現在

簡単な解決策はmaya2022 以前の2020,2019バージョンを起動して そこでmel2pyを使うことだ。

A simple solution is to launch a maya2020 or maya2019 version prior to maya2022 and use mel2py there.

githubで解決していると思いダウンロードして試したが無理だった

https://github.com/LumaPictures/pymel/blob/master/pymel/tools/mel2py/melparse.py

import pymel_master.tools.mel2py as mel2py
mel_command = 'setDrivenKeyframe "-currentDriver pCube1.translateY pCube2.translateX";setDrivenKeyframe "-currentDriver pCube1.translateY pCube2.translateY";setDrivenKeyframe "-currentDriver pCube1.translateY pCube2.translateZ";'
pythonCode = mel2py.mel2pyStr(mel_command, pymelNamespace='pm')
print(pythonCode)



import pymel_master.tools.mel2py as mel2py
mel_command = '$currentNodes = `ls -sl -l`;'
pythonCode = mel2py.mel2pyStr(mel_command, pymelNamespace='pm')
print(pythonCode)

python3 Error: AttributeError: file C:\Program Files\Autodesk\Maya2023\Python\lib\site-packages\pymel\tools\mel2py\melparse.py line 438: ‘str’ object has no attribute ‘lineno

StackOverFlowのように

https://stackoverflow.com/questions/73656852/maya-2023-pymel-i-cant-access-mel2py-with-python3/73839888#73839888

上記エラーがでて無理だった。

1行ならどうにかなるが、関数などの複数行だとこのlinenoが取得できないようでバグるものしか作れなかった

        # cycle through our kwargs and format them
        for flag, value in kwargs.items():
            print("melparse.py  - format_command() - "+" flag= "+str(flag)+" ,value= "+str(value))
            if value is None:
                value = '1'

            # multi-use flag
            #    mel:     ls -type "transform" -type "camera"
            #    python:    ls( type=["transform", "camera"] )
            if isinstance(value, list):
                #sep = ', '
                # if len(value) > t.lexer.format_options['kwargs_newline_threshhold']:
                #    sep = ',\n\t'
                #pargs.append( '%s=[%s]' % ( flag, sep.join(value) )  )
                value = assemble(t, 'multiuse_flag', ', ', value, matchFormatting=True)
                #pargs.append(Token('%s=[%s]' % (flag, value), None, flag.lineno))
                pargs.append(Token('%s=[%s]' % (flag, value), None, 0))#mycode
            else:
                print("melparse.py  - format_command() -  flag= "+str(flag))
                #pargs.append(Token('%s=%s' % (flag, value), None, flag.lineno))
                pargs.append(Token('%s=%s' % (flag, value), None, 0))#mycode

本体の更新に期待する。

[maya] python prefixHierarchy remove suffix

Python

    def delete_suffixHierarchy_remove_suffix(self,suffix):
        print("-----------prefixHierarchy_remove_suffix-----------start")
        #suffix="fat:"
        # Get the prefix the user entered
        #
        # Get a list of all descendents (The nodes are ordered from
        # leaf to root
        #    
        currentNodes=pm.mel.eval("listRelatives -pa -ad `ls -sl -l`")
        print("currentNodes 1= "+str(currentNodes))
        # add the prefix to each descendent node
        #
        if len(currentNodes)>0:
            for i in range(0,len(currentNodes)):
                #pm.mel.prefixNode(prefix, currentNodes[i])
                newName=currentNodes[i].replace(suffix,"")
                print("newName= "+newName)
                cmds.rename(currentNodes[i], newName)

            
        currentNodes=cmds.ls(l=1, sl=1)
        print("currentNodes 2= "+str(currentNodes))
        # get a list of nodes on the list
        # add the prefix to each node on the active list
        #
        if len(currentNodes)>0:
            for i in range(0,len(currentNodes)):
                #pm.mel.prefixNode(prefix, currentNodes[i])
                newName=currentNodes[i].replace(suffix,"")
                print("newName= "+newName)
                cmds.rename(currentNodes[i], newName)
        print("-----------prefixHierarchy_remove_suffix-----------end")

mel

global proc prefixHierarchy( )
{
	string $ok		= (uiRes("m_prefixHierarchy.kOK"));
	string $cancel	= (uiRes("m_prefixHierarchy.kCancel"));
	string $result = `promptDialog
		-title (uiRes("m_prefixHierarchy.kPrefixHierarchy")) 
		-message (uiRes("m_prefixHierarchy.kEnterPrefix")) 
		-text "prefix_"
		-button $ok  
		-button $cancel 
		-defaultButton $ok  
		-cancelButton $cancel 
		-dismissString $cancel `;

	// If the result was "OK", then proceed
	//
	if ( $result == $ok ) {

		// Get the prefix the user entered
		//
		string $prefix = `promptDialog -q`;

		// Get a list of all descendents (The nodes are ordered from
		// leaf to root
		//	
		string $currentNodes[] = eval("listRelatives -pa -ad `ls -sl -l`");
	
		// add the prefix to each descendent node
		//
		if ( size( $currentNodes ) > 0 ) {
			for( $i=0; $i < size( $currentNodes ); $i++ ) {
				prefixNode( $prefix, $currentNodes[$i] );
			}
		}

		// get a list of nodes on the list
		$currentNodes = `ls -sl -l`;
	
		// add the prefix to each node on the active list
		//
		if ( size( $currentNodes ) > 0 ) {
			for( $i=0; $i < size( $currentNodes ); $i++ ) {
				prefixNode( $prefix, $currentNodes[$i] );
			}
		}
	}
}

[UnrealEngine] UE Python で TGAを書き出す方法

task = unreal.AssetExportTask()
task.set_editor_property('automated', True)
task.set_editor_property('filename', outfilepath)
task.set_editor_property('object', texture2d)
task.set_editor_property('prompt', False)
task.set_editor_property('exporter', unreal.TextureExporterTGA())

check = unreal.Exporter.run_asset_export_task(task)
      
if check==True:
    pass
else:
    alert(u"tga イメージの生成に失敗しました")

参考

https://zhuanlan.zhihu.com/p/240826602