ousttrue/pymeshio — pull request #13 by griffon-9 (2012-09-04 12:56:42+00:00)
Title: NEW FEATURE (export_pmx / import_pmx) : BDEF4

PMDには一つの頂点に対してウェイトを設定できるボーンは2つまでという制限がありましたが、Blender上でモデルデータを作ってみると2つまででは足りないと感じる場面が何度かありました。一方でPMXは最大で4つまでウェイトを設定できると思います。
そこでPMXエクスポート時にウェイト値が大きい物から順に最大4つまでウェイトを出力できるようにするコードを作成してみました。

基本的な設計としては、新設したExtendedWeightsクラスにBlender上で設定されているウェイト値を一度蓄積しておき、それに基づいてexport_pmxにおいて変形情報を組み立てるようになっています。

ウェイト値の収集は OneSkinMesh に新しく追加したメソッドで行っています。Meshの各頂点についてVertex Groupの名前とウェイト値をtupleにして一旦全て収集します。ただし"_"で始まる名前のVertex Groupは除外します。これは"_MMD_SHAPE"の除外を意図したものです。

export_pmxに追加したクラスDeformBuilderはウェイト値の数に応じてBdef1, Bdef2, Bdef4 のオブジェクトを作り分けます。まず、Vertex Group名をモデルに存在するボーン名と比較して存在しないものを除外し、残ったものの中でウェイト値が大きい物から順に最大で4つを抽出します。そしてVertex Group名をボーンIndexに変換して、残ったウェイト値の個数に基づいてBdef1, Bdef2, Bdef4のいずれかのオブジェクトを作成します。ウェイト値が3個になった場合は4番目のウェイトとしてIndex 0のボーンに対してウェイト0.0を設定します。（PMDエディタはそうしているように思えます。）

ウェイト値の合計が1.0になるように調整していますが、これはMikuMikuDance Ver.7.39では4つのウェイトの合計が1.0でないと正常に変形しない、というような話を以前どこかのサイトで見かけた気がするので、一応そのようにしています。

従来のウェイトをハンドリングするロジックもそのまま残っており、PMD出力は従来ロジックのままです。PMD/PMXどちらへの出力かによらず両方のロジックが動作してしまうため、頂点数が多い場合にはメモリ消費が多くなったり、重たくなったりしてしてしまう可能性があるのが弱点です。