頂点インデックスによるミラー反転

(トポロジーによる)ミラー反転を利用しても、頂点が重なっている場合は、ミラー反転が上手く機能しない。
これは、軸対称にある頂点の1つにしかミラー反転が作用しないからである。

ミラーモディファイアを適用したものであれば、頂点インデックスは左右で同じような採番になるので、予め左右対称になっている頂点(インデックス)を紐づけして、外部ファイルに保存しておけば良い。

スクリプト①(紐づけ)

import bpy
import bmesh
import json
import os

bpy.ops.object.mode_set(mode = 'EDIT')

mesh = bpy.context.active_object.data
bm = bmesh.from_edit_mesh(mesh)
bm.verts.ensure_lookup_table()

dict1 = {}
for v1 in bm.verts:
    if v1.co.x > 0:
        for v2 in bm.verts:
            if v1.co.x == -(v2.co.x) and v1.co.y == v2.co.y and v1.co.z == v2.co.z:
                if v1.index in dict1:
                    dict1[v1.index] = dict1[v1.index] + "," + str(v2.index)
                else:
                    dict1[v1.index] = str(v2.index)

dict2 = {}
for k1 in dict1.keys():
    list = []
    for k2 in dict1.keys():
        if dict1[k1] == dict1[k2]:
            list.append(k2)
    dict2[k1] = dict1[k1].split(",")[list.index(k1)]

current_folder = os.path.dirname(bpy.data.filepath)
path = current_folder + "\\" + "mirror_verts.json"
with open(path, "w") as json_file:
    json.dump(dict2, json_file)

スクリプト②(ミラー反転)

import bpy
import bmesh
import json
import os

bpy.ops.object.mode_set(mode = 'EDIT')

mesh = bpy.context.active_object.data
bm = bmesh.from_edit_mesh(mesh)
bm.verts.ensure_lookup_table()

current_folder = os.path.dirname(bpy.data.filepath)
path = current_folder + "\\" + "mirror_verts.json"

dict3 = {}
with open(path) as json_file:
    dict3 = json.load(json_file)
        
print(dict3)

for k, v in dict3.items():
    bm.verts[int(v)].co.x = -(bm.verts[int(k)].co.x)
    bm.verts[int(v)].co.y = bm.verts[int(k)].co.y
    bm.verts[int(v)].co.z = bm.verts[int(k)].co.z
    
bpy.ops.object.mode_set(mode = 'OBJECT')
bpy.ops.object.mode_set(mode = 'EDIT')

手順

  • Workspace を Scripting に変更する
  • スクリプト①をコピペする
  • 実行する

  • 「mirror_verts.json」というファイルが作成されたことを確認する

  • シェイプキーを作成する(任意)
  • 向かって右(+x)側の頂点を動かす
  • スクリプト②をコピペする
  • 実行する

  • ミラー反転されたことを確認する

所感

  • スクリプトには必要最低限のコードしか書いていないので、適宜修正して使ってほしい。
  • 個人的に右側(+x)しか動かさないので、左側(-x)を動かす場合には対応していない。モチベがあれば対応させたい。
  • 外部ファイルに書き出すのはスマートではないので、シェイプキーの basis を基に紐づけするのが良いかもしれない。モチベがあれば作成したい。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です