Files
visemes/visemes.py

112 lines
3.8 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Credits:
# Thanks to https://github.com/ShyWolf42/Copy-to-MMD-Visemes
# Thanks to https://github.com/teamneoneko/Cats-Blender-Plugin
bl_info = {
"name": "Visemes Converter Tool",
"author": "MikiMleam",
"version": (3, 0, 0),
"blender": (3, 0, 0),
"location": "View3D > Sidebar > Visemes Tool",
"description": (
"Generates VRChat visemes (vrc.v_* + vrc.blink) from MMD blendshapes, "
"and converts blendshapes from English/VRChat to Japanese MMD format"
),
"category": "Rigging",
}
import bpy
from operators import (
VRCVIS_OT_AutoDetect,
VRCVIS_OT_Preview,
VRCVIS_OT_UpdatePreview,
VRCVIS_OT_Generate,
VRCVIS_OT_RemoveAll,
VRCVIS_OT_Reorder,
VRCVIS_OT_MMDAutoDetect,
VRCVIS_OT_MMDConvert,
VRCVIS_OT_MMDRemove,
)
from panels import VRCVIS_PT_Panel, viseme_enum_items
from utilities.functions import MMD_JP_MAPPING
from utilities.helpers import _ps, _restore_shapekey_values
_CLASSES = [
VRCVIS_OT_AutoDetect,
VRCVIS_OT_Preview,
VRCVIS_OT_UpdatePreview,
VRCVIS_OT_Generate,
VRCVIS_OT_RemoveAll,
VRCVIS_OT_Reorder,
VRCVIS_OT_MMDAutoDetect,
VRCVIS_OT_MMDConvert,
VRCVIS_OT_MMDRemove,
VRCVIS_PT_Panel,
]
_MMD_PROPS = [f'vrcvis_mmd_{suffix}' for _, suffix, _en, _ in MMD_JP_MAPPING]
def register():
for cls in _CLASSES:
bpy.utils.register_class(cls)
bpy.types.Scene.vrcvis_mesh = bpy.props.StringProperty(
name='Mesh', description='Mesh su cui operare', default='')
bpy.types.Scene.vrcvis_mouth_a = bpy.props.StringProperty(
name='Mouth A', description='Shape key bocca aperta (あ / A)', default='')
bpy.types.Scene.vrcvis_mouth_o = bpy.props.StringProperty(
name='Mouth O', description='Shape key bocca rotonda (お / O)', default='')
bpy.types.Scene.vrcvis_mouth_ch = bpy.props.StringProperty(
name='Mouth CH', description='Shape key bocca stretta (い / CH)', default='')
bpy.types.Scene.vrcvis_blink = bpy.props.StringProperty(
name='Blink', description='Shape key occhi chiusi (まばたき / Blink)', default='')
bpy.types.Scene.vrcvis_intensity = bpy.props.FloatProperty(
name='Intensità', description='Moltiplicatore globale dei pesi',
default=1.0, min=0.0, max=2.0, step=1)
bpy.types.Scene.vrcvis_overwrite = bpy.props.BoolProperty(
name='Sovrascrivi esistenti',
description='Rigenera le shape key già presenti',
default=True)
bpy.types.Scene.vrcvis_preview_active = bpy.props.BoolProperty(
name='Preview attiva', default=False)
bpy.types.Scene.vrcvis_preview_viseme = bpy.props.EnumProperty(
name='Viseme', description='Viseme da mostrare in anteprima',
items=viseme_enum_items)
for jp_name, suffix, _en, _ in MMD_JP_MAPPING:
setattr(bpy.types.Scene, f'vrcvis_mmd_{suffix}',
bpy.props.StringProperty(
name=jp_name,
description=f'Shape key sorgente per {jp_name}',
default=''))
def unregister():
scene = bpy.context.scene if bpy.context else None
if _ps.active and scene:
mesh_name = scene.get('vrcvis_mesh', '')
if mesh_name and mesh_name in bpy.data.objects:
_restore_shapekey_values(bpy.data.objects[mesh_name])
_ps.active = False
for cls in reversed(_CLASSES):
bpy.utils.unregister_class(cls)
for prop in (
'vrcvis_mesh', 'vrcvis_mouth_a', 'vrcvis_mouth_o', 'vrcvis_mouth_ch',
'vrcvis_blink', 'vrcvis_intensity', 'vrcvis_overwrite',
'vrcvis_preview_active', 'vrcvis_preview_viseme',
*_MMD_PROPS,
):
if hasattr(bpy.types.Scene, prop):
delattr(bpy.types.Scene, prop)
if __name__ == '__main__':
register()