First Commit

This commit is contained in:
2026-04-08 11:47:23 +02:00
committed by GitHub
parent 67b5d118c2
commit 96d567eb9e
11 changed files with 1050 additions and 0 deletions

130
panels/main_panel.py Normal file
View File

@@ -0,0 +1,130 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import bpy
from utilities.constants import MMD_VISEME_COUNT
from utilities.functions import MMD_JP_MAPPING, VRC_ORDER, build_viseme_map
def viseme_enum_items(self, context):
vmap = build_viseme_map('_', '_', '_')
items = [(k, k, '') for k in vmap.keys()]
items.append(('vrc.blink', 'vrc.blink', ''))
return items
class VRCVIS_PT_Panel(bpy.types.Panel):
bl_idname = 'VIEW3D_PT_visemes_converter'
bl_label = 'Visemes Converter'
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Visemes Tool'
def draw(self, context):
layout = self.layout
scene = context.scene
box = layout.box()
box.label(text='Mesh', icon='MESH_DATA')
mesh_objects = [o for o in bpy.data.objects if o.type == 'MESH' and o.data.shape_keys]
if not mesh_objects:
box.label(text='Nessuna mesh con shape key', icon='ERROR')
return
box.prop_search(scene, 'vrcvis_mesh', bpy.data, 'objects', text='')
mesh_name = scene.vrcvis_mesh
if not mesh_name or mesh_name not in bpy.data.objects:
layout.label(text='Seleziona una mesh', icon='INFO')
return
obj = bpy.data.objects[mesh_name]
if obj.type != 'MESH' or not obj.data.shape_keys:
layout.label(text='Mesh senza shape key', icon='ERROR')
return
layout.separator(factor=0.3)
box2 = layout.box()
box2.label(text='VRChat Visemes (MMD → vrc.*)', icon='SHAPEKEY_DATA')
row = box2.row()
row.operator('vrc_viseme.auto_detect', icon='VIEWZOOM', text='Auto-rileva (MMD → VRC)')
box2.separator(factor=0.5)
row = box2.row(align=True)
row.label(text='A (あ):')
row.prop_search(scene, 'vrcvis_mouth_a', obj.data.shape_keys, 'key_blocks', text='')
row = box2.row(align=True)
row.label(text='O (お):')
row.prop_search(scene, 'vrcvis_mouth_o', obj.data.shape_keys, 'key_blocks', text='')
row = box2.row(align=True)
row.label(text='CH (い):')
row.prop_search(scene, 'vrcvis_mouth_ch', obj.data.shape_keys, 'key_blocks', text='')
row = box2.row(align=True)
row.label(text='Blink:')
row.prop_search(scene, 'vrcvis_blink', obj.data.shape_keys, 'key_blocks', text='')
box2.separator(factor=0.5)
box2.prop(scene, 'vrcvis_intensity', text='Intensità')
box2.prop(scene, 'vrcvis_overwrite', text='Sovrascrivi esistenti')
box2.separator(factor=0.5)
row = box2.row(align=True)
row.scale_y = 1.2
if scene.vrcvis_preview_active:
row.operator('vrc_viseme.preview', text='Stop Preview', icon='PAUSE')
row2 = box2.row(align=True)
row2.prop(scene, 'vrcvis_preview_viseme', text='')
row2.operator('vrc_viseme.update_preview', text='', icon='FILE_REFRESH')
else:
row.operator('vrc_viseme.preview', text='Preview Viseme', icon='PLAY')
box2.separator(factor=0.5)
row = box2.row(align=True)
row.scale_y = 1.4
row.operator('vrc_viseme.generate', icon='TRIA_RIGHT')
row2 = box2.row(align=True)
row2.operator('vrc_viseme.reorder', icon='SORTSIZE')
row2.operator('vrc_viseme.remove_all', icon='X')
if obj.data.shape_keys:
existing_vrc = [k.name for k in obj.data.shape_keys.key_blocks if k.name.startswith('vrc.')]
if existing_vrc:
total = len(VRC_ORDER)
box5 = box2.box()
box5.label(text=f'{len(existing_vrc)}/{total} vrc.* presenti', icon='CHECKMARK')
col = box5.column(align=True)
for name in VRC_ORDER:
r = col.row(align=True)
r.label(text=name, icon='CHECKBOX_HLT' if name in existing_vrc else 'CHECKBOX_DEHLT')
layout.separator(factor=0.3)
box_mmd = layout.box()
box_mmd.label(text='Converti in MMD (EN/VRC → JP)', icon='FILE_REFRESH')
row = box_mmd.row()
row.operator('vrc_viseme.mmd_auto_detect', icon='VIEWZOOM', text='Auto-rileva (EN → JP)')
box_mmd.separator(factor=0.4)
box_mmd.label(text='--- MMD Visemes ---', icon='SHAPEKEY_DATA')
for _jp, suffix, en_label, _ in MMD_JP_MAPPING[:MMD_VISEME_COUNT]:
row = box_mmd.row(align=True)
row.label(text=en_label + ':')
row.prop_search(scene, f'vrcvis_mmd_{suffix}',
obj.data.shape_keys, 'key_blocks', text='')
box_mmd.separator(factor=0.4)
box_mmd.label(text='--- Altre forme ---', icon='SHAPEKEY_DATA')
for _jp, suffix, en_label, _ in MMD_JP_MAPPING[MMD_VISEME_COUNT:]:
row = box_mmd.row(align=True)
row.label(text=en_label + ':')
row.prop_search(scene, f'vrcvis_mmd_{suffix}',
obj.data.shape_keys, 'key_blocks', text='')
box_mmd.separator(factor=0.5)
row = box_mmd.row(align=True)
row.scale_y = 1.4
row.operator('vrc_viseme.mmd_convert', icon='DUPLICATE')
row.operator('vrc_viseme.mmd_remove', icon='X')