• [Blender]オブジェクト境目の法線を編集してPMXにエクスポート

    2017-01-18 00:494
    人物モデルの頭部と胴体を別オブジェクトで作成する場合、境目の頂点を2つのオブジェクトで一致させても、オブジェクトの境目が目立ってしまいます。



    原因は、境目で重なっている頂点の法線が違うからです。二つのオブジェクトを一時的に結合して、編集モードで頂点法線を表示すると、境目で重なる2頂点の法線の向きが違っていて、V字に分かれているのが確認できます。



    これをPMXにエクスポートすると、この法線もそのままエクスポートされます。PMXエディタで法線を確認できます。



    MMDの標準シェーダーはトゥーン調なので、この境目はそれほど目立ちませんが、シェーダーエフェクトを適用して別のシェーダーに切り替えると、はっきり現れてしまいます。



    この問題を解決するには、V字に分かれている法線を同じ向きになるように編集する必要があります。

    Blenderには法線を直接編集するモディファイアやアドオン(Y.A.V.N.E.など)がありますが、これらはミラーやSubsurfなどの生成系モディファイアと併用できません。そこで、法線を直接編集するのではなく、データ転送モディファイア(Data Transfer)を使うことにします。

    まず、二つのオブジェクトのトランスフォーム(位置・回転・拡大縮小)を適用しておきます。

    そのうえで、編集モードでオブジェクトの境目に接する面をループ選択し、Shift+Dで複製します。複製した面をPで別オブジェクトにします。



    頭部・胴体から分離した境目のオブジェクト2個を選択し、Ctrl+Jで結合します。



    結合したオブジェクトの編集モードに切り替え、重なっている境目の頂点をすべて選択します。重なって隠れている頂点をすべて選択するには、ワイヤーフレーム表示に切り替えるといいです。頂点を選択した状態で、Ctrl+Vで頂点メニューを表示し、「重複頂点を削除」(Remove Doubles)を実行します。



    境目のオブジェクトは邪魔なので、別のレイヤーに移して表示しないようにします。元の頭部オブジェクト・胴体オブジェクトに戻って、それぞれの編集モードで境目の頂点を選択し、頂点グループを追加します。ここでは「boundary」としました。



    データ転送モディファイアを追加します。ミラーやSubsurfがあるときは、その下に追加します


    データ転送元オブジェクトに、境目から分離したオブジェクトを指定し、面コーナーデータにチェックを入れ、カスタム法線をクリックします。これで転送元オブジェクトから法線が転送されます。ただし、法線データを受け取りたいのは境目の頂点だけなので、頂点グループ「boundary」を指定して、転送範囲をそのグループに限定します。

    2つのオブジェクトそれぞれに上記のようなデータ転送モディファイアを追加することで、オブジェクトの境目が無くなりました。



    ここで注意しなければならないのは、リグを組むときは、法線データ転送元のオブジェクト(分離した境目のオブジェクト)にもスキニングを施しておく必要があることです。頭部・胴体がポーズで変形しているのに、法線データ転送元のオブジェクトが一緒に変形していないと、その状態の法線がそのまま変形後の頂点に転送されてしまうので、おかしくなります。頭部・胴体の変形ウェイトを法線データ転送元のオブジェクトに転送するとよいでしょう。

    これでBlender上は境目の問題が解消しました。しかし、拙作PMXエクポーターを使ってPMXに法線の編集結果をエクスポートするには、これだけでは足りません。カスタム法線をエクスポートするには、頂点データプロパティの「自動スムーズ」を有効にする必要があります


    自動スムーズを有効にした場合、角度に適切な数値を入力しなければなりません。ここでは「180°」にしました。あまり小さい値にすると、スムーズが効かなくなります。スムーズが効かない辺では、PMXエクスポート時に辺分離されるので、PMXの頂点数が増大します。

    自動スムーズを有効にしてPMXにエクスポートし、PMXエディタで法線を表示すると、下図のようになりました。



    境目の頂点の法線を1つにまとめる(V字になっていない状態にする)ことに成功しました。

  • 広告
  • PMXエクスポーター用のサンプルデータを公開

    2016-10-28 23:39
    左の配布動画で、Blender用PMXエクスポーター
    の仕様を簡単に説明しましたが、動画や文章で説明するのも限界があるので、サンプルデータを公開しました。




    Neko GUMI
    https://sketchfab.com/models/48f050aaa7af4132bfba812b822fdbbd



    (ブロマガではSketchfabの3DViewerを埋め込むことができませんでした・・・)

    このモデルをPMXにエクスポートするには、このモデル用のmanifest.txtが必要です。これは以下のファイルに含まれています。

    MMD関連保管庫: http://ux.getuploader.com/suwatoh_mmd1/
    ねこグミPMX作成ツール Ver. 1.004対応版 ねこグミPMX作成ツール1004.zip

    このzipには、manifest.txtのほかに、Windows環境限定ですが、Blenderをバックグラウンドで動作させてPMXエクスポーターを実行するツールも含まれています。エクスポートの手順については、zipに同梱したPDFドキュメントをお読みください。

    サンプルデータは、PMXエクスポーターが対応する要素をできるだけ盛り込みました(というか、このデータをエクスポートするためにエクスポーターを作っていた?)。モデルをいじっていただければ、エクスポーターの仕様を把握しやすくなるかと思います。モデルデータやmanifest.txtは、ご自由にコピペしてお使いください。


  • [Blender]スペシャルメニューに任意のメニューを追加するアドオンを作る方法

    2016-09-29 00:48
    Blenderの3DViewで呼び出せるスペシャルメニューに、任意のメニューを追加するアドオンを作る方法を説明します。



    上は、オブジェクトモードのスペシャルメニューにカメラ設定メニューを追加した画像です。この程度なら、ごく簡単なスクリプトで済みます。
    bl_info = {
    "name": "Cameras Specials",
    "author": "suwatoh",
    "version": (1, 0, 0),
    "blender": (2, 77, 0),
    "location": "View3D > Specials",
    "description": "Prepend cameras to the specials menu",
    "warning": "",
    "wiki_url": "",
    "category": "3D View",
    }

    import bpy


    def menu_func(self, context):
    self.layout.menu("VIEW3D_MT_view_cameras")


    def register():
    bpy.types.VIEW3D_MT_object_specials.prepend(menu_func)


    def unregister():
    bpy.types.VIEW3D_MT_object_specials.remove(menu_func)


    if __name__ == "__main__":
    register()

    スクリプトの説明をします。まず、下のほうから。
    def register():
    bpy.types.VIEW3D_MT_object_specials.prepend(menu_func)


    def unregister():
    bpy.types.VIEW3D_MT_object_specials.remove(menu_func)
    これはregisterという関数とunregisterという関数を定義しています。registerはアドオンを有効化するときにBlenderから呼び出される関数です。unregisterはアドオンを無効化するときにBlenderから呼び出される関数です。スクリプトの最後に
    if __name__ == "__main__":
    register()
    と書いておくと、Blenderのテキストエディターからもスクリプトを実行できます。アドオンを試行するのに便利なので、たいていのアドオンはこのように書いています。if文の下の行を「unregister()」と書き換えて実行すると、アドオンを無効化するのと同じになります。

    話をregister関数に戻します。「bpy.types.VIEW3D_MT_object_specials」というのが出てきますが、これがオブジェクトモードのスペシャルメニューを表しています。

    メニュー関連には共通してappend・prepend・removeというメソッドが使えるようになっています。appendはメニューの最後に新たな項目を追加します。prependはメニューの先頭に新たな項目を追加します。removeはメニューに追加した項目を削除します。いずれも、メニューを指定する関数を引数とする必要があります。上の例では「menu_func」を指定しています。その定義はすぐ上のほうにあります。
    def menu_func(self, context):
    self.layout.menu("VIEW3D_MT_view_cameras")
    メニューを指定する関数は、必ず、2つの引数を受けとるように定義しなければなりません。第1引数のselfは、Pythonのインスタンスメソッドのお約束で、ここにはメニューへの参照が渡されます。第2引数のcontextには、Blender上の様々な要素にアクセスするための参照が渡されます。

    「self.layout」は、ここではオブジェクトモードのスペシャルメニューのlayout属性となります。Blenderのメニュー要素には、layout属性を通して、表示に関する様々な機能にアクセスすることが出来るようになっています。

    menuメソッドはその名の通り、追加するメニュー項目を指定するもので、上の例では「VIEW3D_MT_view_cameras」を指定しています。これはビューメニューのサブメニュー・カメラ設定を指しています。

    ここまでの説明で、「bpy.types.VIEW3D_MT_object_specials」と「VIEW3D_MT_view_cameras」の部分を書き換えると、メニューをいろいろ変更できることがわかると思います。

    他のスペシャルメニューは、次のようになっています。
    • bpy.types.VIEW3D_MT_edit_mesh_specials … メッシュ編集モード
    • bpy.types.VIEW3D_MT_armature_specials … アーマチュア編集モード
    • bpy.types.VIEW3D_MT_pose_specials … ポーズモード
    他にどのようなものがあるのか、それを調べるのにAPI Navigatorアドオンが便利です。このアドオンは、Blenderに標準でインストールされていますが、デフォルトでは無効になっているので、ユーザー設定で有効化してください。

    ウィンドウレイアウトをScriptingに変更し、テキストエディタの左上にある「+」をクリックしてツールシェルフを表示すると、API Navigatorパネルが見つかります。3DView上のメニュー関連は「bpy.types.VIEW3D_MT」で始まる慣例があるので、下図のようにフィルタをかけると探しやすくなります。



    スクリプトの先頭の「bl_info」は、ユーザー設定に表示される内容を指定します。その次の「import bpy」は、「bpy」で始まる名前のものをスクリプトで利用可能にするための文です。これを冒頭部分に書かないと、「bpy」を書いた行でスクリプトの処理がエラーになってしまいます。

    説明は以上です。