Skip to content

Instantly share code, notes, and snippets.

@Taremin
Created May 8, 2020 12:19
Show Gist options
  • Save Taremin/983f5c46ef4ae2efb2252c1fd11c2fd7 to your computer and use it in GitHub Desktop.
Save Taremin/983f5c46ef4ae2efb2252c1fd11c2fd7 to your computer and use it in GitHub Desktop.
HumanoidボーンのJSONをつかって頂点グループ(ウェイト)を置換するBlenderアドオン
import bpy
import json
import numpy
bl_info = {
'name': 'Taremin Replace Weight',
'category': '3D View',
'author': 'Taremin',
'location': 'View 3D > UI > Taremin Replace Weight',
'description': "",
'version': [0, 0, 1],
'blender': (2, 80, 0),
'wiki_url': '',
'tracker_url': '',
'warning': '',
}
class OBJECT_OT_TareminReplaceWeight(bpy.types.Operator):
bl_idname = 'taremin.replace_weight'
bl_label = 'replace'
bl_description = ''
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
props = context.scene.trw_props
from_dict = json.load(open(bpy.path.abspath(props.from_json)))
to_dict = json.load(open(bpy.path.abspath(props.to_json)))
active = bpy.context.window.view_layer.objects.active
convert_dict = self.create_convert_dict(from_dict, to_dict)
if props.is_dissolve_upper_chest:
self.dissolve(
active,
active.vertex_groups.get(from_dict['UpperChest']),
active.vertex_groups.get(from_dict['Chest'])
)
for i in active.vertex_groups:
if i.name in convert_dict:
i.name = convert_dict[i.name]
elif props.is_remove_not_humanoid_bones:
active.vertex_groups.remove(i)
return {'FINISHED'}
def create_convert_dict(self, from_dict, to_dict):
convert_dict = {}
for (key, value) in from_dict.items():
if from_dict[key] is not None and to_dict[key] is not None:
convert_dict[value] = to_dict[key]
return convert_dict
def dissolve(self, obj, child_vertex_group, parent_vertex_group):
selected = numpy.zeros(len(obj.data.vertices), dtype=numpy.bool)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.vertex_group_set_active(group=child_vertex_group.name)
bpy.ops.object.vertex_group_select()
bpy.ops.object.mode_set(mode='OBJECT')
obj.data.vertices.foreach_get('select', selected)
for v in numpy.array(obj.data.vertices)[selected]:
vi = [v.index]
parent_vertex_group.add(vi, child_vertex_group.weight(v.index),
'ADD')
child_vertex_group.remove(vi)
class TareminReplaceWeightProps(bpy.types.PropertyGroup):
from_json: bpy.props.StringProperty(
subtype="FILE_PATH"
)
to_json: bpy.props.StringProperty(
subtype="FILE_PATH"
)
is_remove_not_humanoid_bones: bpy.props.BoolProperty(
name="Humanoidで使用しない頂点グループの削除",
description="Humanoidで使用しない頂点グループを削除します"
)
is_dissolve_upper_chest: bpy.props.BoolProperty(
name="UpperChestの溶解",
description="UpperChestの頂点グループをChestに結合します"
)
class VIEW3D_PT_TareminReplaceWeightPanel(bpy.types.Panel):
bl_label = 'Taremin Replace Weight'
bl_region_type = 'UI'
bl_space_type = 'VIEW_3D'
bl_category = 'Taremin Replace Weight'
def draw(self, context):
layout = self.layout
box = layout.box()
col = box.column(align=True)
invalid_context = False
props = context.scene.trw_props
row = col.row(align=True)
col.prop(props, 'from_json')
col.prop(props, 'to_json')
row = col.row(align=True)
row.prop(props, 'is_remove_not_humanoid_bones')
row = col.row(align=True)
row.prop(props, 'is_dissolve_upper_chest')
row = col.row(align=True)
row.operator(OBJECT_OT_TareminReplaceWeight.bl_idname)
classesToRegister = [
VIEW3D_PT_TareminReplaceWeightPanel,
OBJECT_OT_TareminReplaceWeight,
TareminReplaceWeightProps
]
def register():
for value in classesToRegister:
bpy.utils.register_class(value)
bpy.types.Scene.trw_props = bpy.props.PointerProperty(type=TareminReplaceWeightProps)
def unregister():
for value in classesToRegister:
bpy.utils.unregister_class(value)
del bpy.types.Scene.trw_props
if __name__ == '__main__':
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment