ngSkinToolsのPython API|ウェイトをJSONで書き出し、別モデルへ転写する基本

ngSkinTools 2.4.0のウィンドウと、近接頂点でウェイトを読み込んだジャケットのメッシュ Maya

クリーク・アンド・リバー社のテクニカルアーティストチームが運営する技術ブログ「TECH-COYOTE」に、ngSkinToolsのPython APIの使い方をまとめた記事が2026年9月29日付で公開されています。著者は同チームの長谷川氏で、レイヤーの作成・削除からウェイトの取得、JSONでの書き出しと読み込み、それを使ったウェイト転写の活用例までを、コードつきで扱っています。

ngSkinToolsは、スキンウェイトをレイヤーに分けて非破壊で編集できるMaya用のプラグインです。記事によると、Maya 2027ではAutodeskによる買収・統合によってMayaに正式に組み込まれ、「Skin Tools」という名前になっています。検証環境はMaya 2024.2.4とMaya 2027です。

APIで何ができるか

記事では、APIを使うとスクリプトから次のような処理を行えると整理されています。

  • シーン内のモデルのウェイト情報をJSONで一括書き出し
  • モデル更新時の再バインド
  • 指定したジョイントのウェイトを別レイヤーへ抽出
  • ウェイトデータの一括読み込み
  • 別のスキンクラスター間でのウェイトのコピー
  • レイヤー構成のテンプレート化

APIはngSkinTools2.apiモジュールから使います。maya.cmdsと組み合わせれば、選択したオブジェクトへの一括処理や、独自ツールとしてのUI化もできる、とされています。

Maya 2027のSkin Toolsで増えた2つの機能

APIの前に、統合にあわせてSkin Toolsに加わった機能が2つ紹介されています。1つ目はインフルエンスのロックです。Maya標準のスキニングにある、特定のインフルエンスのウェイトを変更されないように固定する機能がSkin Toolsにも入り、調整済みのジョイントを固定したまま他のジョイントだけを編集できるようになりました。

Mayaのコンポーネントエディタ。スムーズスキンタブの下部にレイヤーを選ぶドロップダウンがあり、Base weightsとNew Layerが並ぶ
コンポーネントエディタの下部でレイヤーを選び、頂点ごとのウェイトを数値で確認・修正できる(画像:TECH-COYOTEより)

2つ目は、コンポーネントエディタからレイヤーごとのウェイトを調整できるようになったことです。以前はコンポーネントエディタで編集してもSkin Tools側のレイヤー情報が優先されるため、レイヤーを使いながら頂点単位で数値を詰めるのが難しかった、と記事は説明しています。今回からはレイヤーを保持したまま、各頂点のウェイトを数値で確認・修正できます。

レイヤーの初期化・一覧・追加・削除

ngSkinToolsのレイヤーは、skinClusterがあっても自動では作られません。記事のコードでは、まずapi.target_info.get_related_skin_cluster()でメッシュからskinClusterを取り、ngst2SkinLayerDataアトリビュートの有無でレイヤー情報があるかを確認して、無ければapi.init_layers()で初期化します。そのうえでレイヤーが1枚も無ければ、ベースのレイヤーを1枚追加しています。

スクリプトを実行してもツールの表示が変わらないときは、メッシュの選択をいったん外して選び直すと表示される、という注意も添えられています。

Skin ToolsのLayers欄に3枚のレイヤーが並び、スクリプトエディタにlist()の結果が表示されている
list()で取得したレイヤーの一覧。Skin Toolsの3枚のレイヤーがそのまま返る(画像:TECH-COYOTEより)

レイヤーの操作はapi.Layers(mesh)で取ったオブジェクトから行います。list()で一覧、add(name=...)で名前を指定して追加、delete(layer)で削除です。削除のサンプルは、一覧を回してレイヤー名が一致したものを消す形になっています。

レイヤーごとのウェイトを取得する

特定のジョイントのウェイトを、レイヤーごとに取り出す例です。api.target_info.list_influences()でインフルエンスの一覧を取り、パスの末尾がジョイント名と一致するもののlogicalIndexを拾って、各レイヤーのget_weights()に渡します。記事ではspine_01のウェイトを、レイヤー0〜2から順に取得しています。

ウェイトをJSONで書き出し、3つの方法で読み込む

書き出しはapi.export_json(mesh, file=path)の1行です。読み込みはapi.import_json()で、vertex_transfer_modeに何を渡すかで対応の取り方を切り替えられます。

  • 頂点番号(VertexTransferMode.vertexId)
  • 近接頂点(VertexTransferMode.closestPoint)
  • UV空間(VertexTransferMode.uvSpace)

頂点番号だけでなく近接頂点とUVでも読み込めるので、トポロジーが違うモデル同士でもウェイトを移せる場合がある、というのが次の活用例につながっています。

活用例1|ローポリの箱で付けたウェイトを服に転写する

ローポリモデルでウェイトを調整し、その結果をハイポリモデルへ移す使い方です。モデルの更新で頂点番号が変わってしまっても、転送方法を切り替えればウェイトを引き継げる、と記事は書いています。

ジャケットのメッシュを2つの箱で囲んだ状態
ウェイトの転写元にした箱と、転写先のジャケット(画像:TECH-COYOTEより)

作例では、ジャケットを囲む箱にウェイトを付けて書き出し、ジャケットに近接頂点で読み込んでいます。ローポリで付けたウェイトをJSONにしておけば、モデルをシーンに読み込んだあとウェイトを塗らずに、ジョイント名を手がかりにウェイトを持ってこられる、という説明です。

緑から白、青へグラデーションでウェイトが付いた箱と、ngSkinTools 2.4.0のウィンドウ
箱に付けたウェイト。インフルエンスはSpine3と左右のHandの3つ(画像:TECH-COYOTEより)

箱のウェイトは、Spine3と左右のHandの3つのインフルエンスで構成されています。これを近接頂点でジャケットに読み込んだ結果が次の画像です。

箱から近接頂点で読み込んだウェイトが色分け表示されたジャケット
箱のウェイトを近接頂点でジャケットに読み込んだ結果(画像:TECH-COYOTEより)

活用例2|レイヤーからレイヤーへウェイトをコピーする

レイヤーが3枚あるメッシュで、指定したジョイントのウェイトを別のレイヤーへ抽出するサンプルです。いちばん下のレイヤーからget_weights()で読んだ値を、下から2番目のレイヤーにset_weights()で書き込みます。あわせて、いちばん下のレイヤーの全インフルエンスのウェイトを、下から3番目のレイヤーへまるごと写す処理も入っています。list()で返るレイヤーは下から順に並ぶ、という点もコードのコメントで触れられています。

APIを使わなくても

記事のまとめでは、ウェイトの抽出や書き出し・読み込みはAPIを使わずに通常のツールとして使うだけでも十分便利で、バックアップやモデル更新時のデータ移行など、日々のスキニング作業を効率化できる場面は多い、と締めくくられています。

全文とサンプルコードはTECH-COYOTEの記事で読めます。APIの仕様はngSkinToolsの公式ドキュメントにまとまっています。

管理人のひとこと

うちのリグ作業は3ds MaxとBlender側なので、Mayaの話は外から見ている立場です。それでも、箱に付けたウェイトを服へ近接頂点で読み込む活用例は、衣装の修正が入るたびにウェイトを塗り直している身には分かりやすい話でした。3ds Maxならスキンラップでやるようなことを、JSONを挟んでジョイント名で引けるので、別のシーンにも持ち出せます。

読み込みを頂点番号・近接頂点・UVの3通りで切り替えられるのも、リテイクでトポロジーが変わったときの逃げ道になります。ウェイトの書き出しは手で回していると必ずどこかで忘れるので、ツールのボタン1つにしておけるのはありがたいところです。

コメント

タイトルとURLをコピーしました