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

こんな感じの状態、

# -*- 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]Mayaで同じトポロジーを持ったオブジェクトの頂点番号を合わせる ReorderVertices (Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)

mel :ReorderVertex;

Plug-in Manager内の「meshReorder. mll」にチェックマークを入れると機能がアクティブになります。
~Mayaの機能「Reorder Vertices」~
Maya2017から新規に追加された機能で、頂点番号を後から調整することが可能です。

以下より
https://help.autodesk.com/view/MAYAUL/2025/JPN/?guid=GUID-8CF82D97-203C-4056-BEF2-EA0CD27336ED

https://help.autodesk.com/view/MAYACRE/JPN/?guid=GUID-8CF82D97-203C-4056-BEF2-EA0CD27336ED

頂点の順序を変更するには

1,頂点の順序を変更するポリゴン オブジェクトのヒストリを削除します。
2,ディスプレイ> ポリゴン > コンポーネント ID > 頂点(Display > Polygons > Component IDs > Vertices)に移動し、オブジェクトの頂点 ID を選択して表示します。
3,頂点の順序を変更(Reorder Vertices)コマンドを選択します。
4,設定する新しい頂点の順序の最初の 3 つの頂点に関連する 3 つの隣接する頂点をクリックします。
(Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)
Maya では、設定した初期パスに基づいて、残りの頂点が並べ替えられます。

注: 頂点の順序を変更(Reorder Vertices)コマンドは、異なるコマンドやツールに切り替えるまでアクティブであるため、希望の順序になるまで新しい頂点の順序を繰り返し試すことができます。


頂点を手動で並べ替えるのではなく、頂点の順序を転送(Transfer Vertex Order)コマンドを使用して、1 つのオブジェクトから別のオブジェクトに頂点の順序を転送できます。

注: 最良の結果を得るには、まず、2 つのメッシュのトポロジが類似していることを確認します。
1 つのメッシュから別のメッシュに頂点の順序を転送するには

1,転送に関連する両方のオブジェクトのヒストリを削除します。
2,ディスプレイ > ポリゴン > コンポーネント ID > 頂点(Display > Polygons > Component IDs > Vertices)に移動し、オブジェクトの頂点 ID を選択して表示します。
頂点の順序を転送(Transfer Vertex Order)コマンドを選択します。
ソース オブジェクト上で 3 つの隣接する頂点をクリックします。
(Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)
ソース オブジェクト上で選択した 3 つの頂点とトポロジ的に関連しているターゲット オブジェクト上の 3 つの隣接する頂点をクリックします。
(Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)
選択した 3 つのベース頂点とソース オブジェクトが相対関係になるように、残りの頂点が並べ替えられます。

参考URL

[maya][mel] MELでファイルの読み取り専用をチェックする。

[maya][mel] Check if a file is read-only in MEL.


global proc MEL_FileReadModeCheck(string $Save_path){
    //MELでファイルの読み取り専用をチェックする。
    print("MEL_FileReadModeCheck("+$Save_path+") \n");
    python("import os");

    int $FileReadOnlybool = python("os.access('"+$Save_path+"', os.W_OK)");
    print("$FileReadOnlybool= "+$FileReadOnlybool+" \n");
    if($FileReadOnlybool==0){
        print("読み取り専用 のため書き込み不可 \n");    
    }else{
        print("書き込み出来ます \n");      
    }
}
MEL_FileReadModeCheck("D:/check_ON.txt");
MEL_FileReadModeCheck("D:/check_OFF.txt");

[maya][mel] get mesh from material

maya mel get mesh from material

hyperShade -objects materialName;
//結果のmeshは選択される

Function



global proc string get_MeshTransform_from_Material_v2(string $mat){   
   string $selected[];
   //選択を取っておく
   $selected =`ls -sl`;
   string $mesh_arr[];
   //$mesh_arr =`hyperShade -objects $mat`;
   //結果のmeshは選択されるので
   hyperShade -objects $mat;
   //選択からとる
   $mesh_arr =`ls -sl`;
   int $mesh_arr_len=size($mesh_arr);
   string $returnStr;
   print("$mesh_arr_len= "+$mesh_arr_len+"\n");
   if($mesh_arr_len==0){
       $returnStr="";
   }else{
       print("$mesh_arr= "+ stringArrayToString($mesh_arr, ", ") +"\n");
       string $mesh= $mesh_arr[0];
       string $trans_arr[] = `listRelatives -noIntermediate -fullPath -parent $mesh`;
       print("$trans_arr= "+ stringArrayToString($trans_arr, ", ") +"\n");
       $returnStr=$trans_arr[0];
   }
   //選択を戻す
   select -cl;
   string $sel;
   for($sel in $selected){
       select -add $sel;
   };
   return $returnStr;
}

[maya][mel] mesh から SkinCluster を取得する

get SkinCluster from mesh

string $SkinSkinCluster = `findRelatedSkinCluster $mesh`;

応用例

        print(">>>>>>>>>>>>>SkinWeightCheck Start>>>>>>>>>>\n");
        select "|parts_low";
        string $selected[] = `ls -sl -long -absoluteName`;
        string $selectedStr = stringArrayToString($selected, ",");   // ","を区切り文字として結合する
        print("SkinWeightCheckの 選択したもの $selected= "+$selectedStr+"\n");
        
        string $mesh[];
        for ($sel in $selected) {
          string $allMesh[] = `listRelatives -ni -pa -ad -typ "mesh" $sel`;
          for ($am in $allMesh) {
            string $trans[] = `listRelatives -ni -pa -p $am`;
            $mesh[size($mesh)] = $trans[0];
          }
        }
        
        $mesh = stringArrayRemoveDuplicates($mesh);
        string $meshStr = stringArrayToString($mesh, ",");   // ","を区切り文字として結合する
        print("SkinWeightCheckの メッシュのみ選別したもの $mesh= "+$meshStr+"\n");
       
       for ($mesh_i in $mesh){
           //print("$mesh_i= "+$mesh_i+"\n");
           string $SkinCluster = `findRelatedSkinCluster $mesh_i`;
           print("メッシュ : "+$mesh_i+"   SkinCluster : "+$SkinCluster+" \n");
           //string $influenceJoint[] = `skinCluster -q -influence $mesh_i`;
           string $influenceJoint[];
           int $inflenceJointBool=0;
           if ( catch ($influenceJoint=`skinCluster -q -influence $mesh_i`)) {
               print("B ------------------------------------------------------------------------------->>>>>メッシュ : "+$mesh_i+" のインフルエンスジョイントがありません!!NG \n");
               $inflenceJointBool=1;
               $AllWeightMeshBool=1;
           }else{
               print("A OK \n");
               $inflenceJointBool=0;
           }
           int $WeightMeshBool=0;
           if($inflenceJointBool==0){
               print("メッシュ : "+$mesh_i+"   influenceJoint : "+$influenceJoint[0]+" \n");
               //vtx[100] の joint1 の weight を取得
               //skinPercent( 'skinCluster1', 'pPlane1.vtx[100]', t='joint1', query=True, value=True)
               //string $weight[] = `skinPercent -query -value -t $influence[0] $SkinCluster $mesh `;
               string $vertex = $mesh_i+".vtx[0]" ;
               //string $weight[] = `skinPercent -query -value $vertex $SkinCluster`;
               float $weightFloatArr[] = `skinPercent -query -value $SkinCluster $vertex`;
               print("$weightFloatArr= "+floatArrayToString($weightFloatArr, ", ")+"\n");
               //skinPercent -query -value skinCluster1 pPlane1.vtx[100];
               float $weightAll=0;
               for ($val in $weightFloatArr){
                  $weightAll=$weightAll + $val;
               }
               print("$weightAll= "+$weightAll+"\n");
               
               if($weightAll>0){
                   print("SkinWeight OK !!! $mesh_i= "+$mesh_i+" OK!!!!!\n");
               }else{
                   $WeightMeshBool=1;
                   print("SkinWeight -----------------------------------------------------------スキンウェイトがありません--Attention !!! $mesh_i= "+$mesh_i+" NG!!!!!\n");
               }
               $AllWeightMeshBool=$AllWeightMeshBool+$WeightMeshBool;
           }

       }//for

参考

[maya][python] findRelatedskinCLuster

https://discourse.techart.online/t/maya-python-findrelatedskincluster/2673

[Maya]特殊な複製 duplicate -upstreamNodes でスキンウェイトごと複製する。

あるようで知らない特殊な複製。

//	選択したノードに至る上流ノード (およびその接続) も複製されます。
//  スキンウェイトなどもコピーされます。
duplicate -upstreamNodes;

上記の場合

duplicate -returnRootsOnly -upstreamNodes; 
group root1 parts_low1;

カスタムした例

global proc skinWeightCopy_JointMeshGroup(){
    //選択
    select root parts_low;
    //スキンウェイトモデルのスキンウェイトごとコピー
    duplicate -returnRootsOnly -upstreamNodes; 
    //グループ化
    group -name "group_dup" root1 parts_low1;
    //元の名前にリネーム
    rename "group_dup|root1" "root";
    rename "group_dup|parts_low1" "parts_low";
}
skinWeightCopy_JointMeshGroup();

combine しながらエクスポート

global proc skinWeightCopy_JointMeshGroup(){
    //選択
    select "|root" "|parts_low";
    //スキンウェイトモデルのスキンウェイトごとコピー
    duplicate -returnRootsOnly -upstreamNodes; 
    //グループ化
    group -name "group_dup" root1 parts_low1;
    //元の名前にリネーム
    rename "group_dup|root1" "root";
    rename "group_dup|parts_low1" "parts_low";
}

global proc group_dup_parts_low_combine(){
    
    
    string $selected[] = `ls -sl -long -absoluteName`;
    //string $selectedStr = stringArrayToString($selected, ",");   // ","を区切り文字として結合する
    //print("選択したもの $selected= "+$selectedStr+"\n");
    string $mesh[];
    for ($sel in $selected) {
      string $allMesh[] = `listRelatives -ni -pa -ad -typ "mesh" $sel`;
      for ($am in $allMesh) {
        string $trans[] = `listRelatives -ni -pa -p $am`;
        $mesh[size($mesh)] = $trans[0];
      }
    }
    
    $mesh = stringArrayRemoveDuplicates($mesh);
    string $meshStr = stringArrayToString($mesh, ",");   // ","を区切り文字として結合する
    print(" メッシュのみ選別したもの $mesh= "+$meshStr+"\n");
    
    

    select -r $mesh; // <メッシュのみ選択
    // Combine実行
      
    // Skeletalだった場合
    string $combine[] = `polyUniteSkinned -ch 0 -muv 1`;
    rename $combine[0] "MeshGP";

    //よけておくグループ化
    select "|root" "parts_low";
    string $group_root;
    $group_root =`group -world -name "group_root"`;
        
    //MeshGPをparts_lowへ入れる
    select "MeshGP";
    string $group_parts_low;
    $group_parts_low =`group -world -name "parts_low"`;
       
    //worldへ移動 
    parent -world "group_dup|root";
    
    //出力用選択
    select "|root" "|parts_low";
    
    // Export
    // --------------------------------------------------------------------------
    simple_model_common_Export(2, "D:/MOSADesign/WorkData/Avatar/008/001/PL_008_001_001/Game/SK_PL_008_001_001_Body.fbx", 0);
    
    //おかたずけ partslow|MeshGP rootを削除
    delete "|parts_low" "|root" "|group_dup";
    
    //worldへ移動 
    parent -world "group_root|root";
    //worldへ移動 
    parent -world "group_root|parts_low"; 
    //group_root 削除
    delete "|group_root";
}



// Export
//--------------------------------------------------------------------------
global proc simple_model_common_Export(int $type, string $expName, int $modelType) {
  showHidden -a;
  // if($type == 2) {
  if ($type == 1) {
    FBXExportSmoothMesh -v 0;
  } else {
    FBXExportSmoothMesh -v 1;
  }
  FBXExportAnimationOnly -v 0;
  FBXExportInAscii -v 0 ;
  FBXExportConvertUnitString cm;
  FBXExportTriangulate -v 0;
  FBXExportSmoothingGroups -v 1;
  FBXExportConstraints -v 0;
  FBXExport -f $expName -s;
}

参考URL

https://help.autodesk.com/cloudhelp/2025/ENU/Maya-Tech-Docs/Commands/duplicate.html

http://me.autodesk.jp/wam/maya/docs/Maya2010/Commands/duplicate.html

maya python 検索用の 正規表現 を作成したテキストフィールドから入力するには?

maya python How can I enter a regular expression for search from the created text field?

import maya.cmds as cmds
import re

def search_objects_by_regex(*args):
    # テキストフィールドから正規表現を取得
    regex_pattern = cmds.textField("regexField", query=True, text=True)

    # シーン内のすべてのオブジェクトを取得
    all_objects = cmds.ls()

    # 正規表現パターンをコンパイル
    try:
        regex = re.compile(regex_pattern)
    except re.error as e:
        cmds.warning(f"Invalid regex pattern: {e}")
        return

    # 正規表現に一致するオブジェクトをフィルタリング
    matching_objects = [obj for obj in all_objects if regex.search(obj)]

    # 結果を表示
    if matching_objects:
        cmds.confirmDialog(title='Search Results', message='\n'.join(matching_objects))
    else:
        cmds.confirmDialog(title='Search Results', message='No matching objects found.')

# UIの作成
if cmds.window("regexSearchWindow", exists=True):
    cmds.deleteUI("regexSearchWindow")

cmds.window("regexSearchWindow", title="Regex Search", widthHeight=(300, 100))
cmds.columnLayout(adjustableColumn=True)
cmds.text(label="Enter Regex Pattern:")
cmds.textField("regexField")
cmds.button(label="Search", command=search_objects_by_regex)
cmds.showWindow("regexSearchWindow")

検索置換の場合

import maya.cmds as cmds
import re

def replace_objects_by_regex(*args):
    # テキストフィールドから正規表現と置換文字列を取得
    regex_pattern = cmds.textField("regexField", query=True, text=True)
    replace_text = cmds.textField("replaceField", query=True, text=True)

    # シーン内のすべてのオブジェクトを取得
    all_objects = cmds.ls()

    # 正規表現パターンをコンパイル
    try:
        regex = re.compile(regex_pattern)
    except re.error as e:
        cmds.warning(f"Invalid regex pattern: {e}")
        return

    # 正規表現に一致するオブジェクトを置換
    replaced_objects = [regex.sub(replace_text, obj) for obj in all_objects]

    # 結果を表示
    if replaced_objects:
        cmds.confirmDialog(title='Replace Results', message='\n'.join(replaced_objects))
    else:
        cmds.confirmDialog(title='Replace Results', message='No objects replaced.')

# UIの作成
if cmds.window("regexReplaceWindow", exists=True):
    cmds.deleteUI("regexReplaceWindow")

cmds.window("regexReplaceWindow", title="Regex Replace", widthHeight=(300, 150))
cmds.columnLayout(adjustableColumn=True)
cmds.text(label="Enter Regex Pattern:")
cmds.textField("regexField")
cmds.text(label="Enter Replace Text:")
cmds.textField("replaceField")
cmds.button(label="Replace", command=replace_objects_by_regex)
cmds.showWindow("regexReplaceWindow")

[UE5]Pythonからダイアログメッセージを表示 unreal.EditorDialog.show_message

import unreal
class hoge:
    def show_messageDialog(self):
        title="タイトル"
        message="メッセージ"
        message_type=unreal.AppMsgType.OK_CANCEL
        
        unreal.EditorDialog.show_message(title,message,message_type, default_value=unreal.AppReturnType.NO, message_category=unreal.AppMsgCategory.WARNING)

class_Ins=hoge()
hoge.show_messageDialog()

参考URL

https://docs.unrealengine.com/5.3/en-US/PythonAPI/class/EditorDialog.html#unreal.EditorDialog