feat: Add KoikatsuBlenderPipeline addon with import/export functionality
- Add core addon files (__init__.py, KKPanel.py, preferences.py, common.py) - Add import pipeline with armature, mesh, and material modification modules - Add export pipeline with material baking and FBX preparation utilities - Add material combiner tool for texture atlas generation and optimization - Add extras utilities for animation, rigging, and asset management - Add bone orientation data from better_fbx for accurate skeletal structure - Add comprehensive documentation and wiki with multi-language support (EN, JP, ZH) - Add animation library retargeting lists for ARP and Rokoko motion capture - Add Rigify integration scripts for advanced rigging workflows - Add shader file (KK Shader V8.0.blend) for material rendering - Add manifest and license files for addon distribution - Add changelog documenting version history and improvements - Initialize complete Blender addon project for Koikatsu character import/export
This commit is contained in:
99
extras/linkshapekeys.py
Normal file
99
extras/linkshapekeys.py
Normal file
@@ -0,0 +1,99 @@
|
||||
'''
|
||||
LINK EYEBROW SHAPEKEYS TO BODY SCRIPT
|
||||
Usage:
|
||||
- Seperate the eyebrow mesh into its own object
|
||||
- Select the eyebrows object, then shift click the body object and run the script to control the eyebrow shapekeys from the body object
|
||||
|
||||
Script 90% stolen from https://blender.stackexchange.com/questions/86757/python-how-to-connect-shapekeys-via-drivers
|
||||
'''
|
||||
import bpy
|
||||
from ..interface.dictionary_en import t
|
||||
from .. import common as c
|
||||
|
||||
def link_keys(shapekey_holder_object, objects_to_link):
|
||||
|
||||
shapekey_list_string = str(shapekey_holder_object.data.shape_keys.key_blocks.keys()).lower()
|
||||
for obj in objects_to_link:
|
||||
bpy.ops.object.select_all(action = 'DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
bpy.ops.object.material_slot_remove_unused()
|
||||
for key in obj.data.shape_keys.key_blocks:
|
||||
if key.name.lower() in shapekey_list_string:
|
||||
if not key.name == obj.data.shape_keys.key_blocks[0]:
|
||||
skey_driver = key.driver_add('value')
|
||||
skey_driver.driver.type = 'AVERAGE'
|
||||
#skey_driver.driver.show_debug_info = True
|
||||
if skey_driver.driver.variables:
|
||||
for v in skey_driver.driver.variables:
|
||||
skey_driver.driver.variables.remove(v)
|
||||
newVar = skey_driver.driver.variables.new()
|
||||
newVar.name = "value"
|
||||
newVar.type = 'SINGLE_PROP'
|
||||
newVar.targets[0].id_type = 'KEY'
|
||||
newVar.targets[0].id = shapekey_holder_object.data.shape_keys
|
||||
newVar.targets[0].data_path = 'key_blocks["' + key.name+ '"].value'
|
||||
skey_driver = key.driver_add('mute')
|
||||
skey_driver.driver.type = 'AVERAGE'
|
||||
#skey_driver.driver.show_debug_info = True
|
||||
if skey_driver.driver.variables:
|
||||
for v in skey_driver.driver.variables:
|
||||
skey_driver.driver.variables.remove(v)
|
||||
newVar = skey_driver.driver.variables.new()
|
||||
newVar.name = "hide"
|
||||
newVar.type = 'SINGLE_PROP'
|
||||
newVar.targets[0].id_type = 'KEY'
|
||||
newVar.targets[0].id = shapekey_holder_object.data.shape_keys
|
||||
newVar.targets[0].data_path = 'key_blocks["' + key.name+ '"].mute'
|
||||
|
||||
|
||||
class link_shapekeys(bpy.types.Operator):
|
||||
bl_idname = "kkbp.linkshapekeys"
|
||||
bl_label = "Link shapekeys"
|
||||
bl_description = t('sep_eye_tt')
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
#separate the eyes from the body object
|
||||
body = c.get_body()
|
||||
c.switch(body, 'EDIT')
|
||||
|
||||
def separateMaterial(matList):
|
||||
for mat in matList:
|
||||
try:
|
||||
def moveUp():
|
||||
return bpy.ops.object.material_slot_move(direction='UP')
|
||||
while moveUp() != {"CANCELLED"}:
|
||||
pass
|
||||
bpy.context.object.active_material_index = body.data.materials.find(mat)
|
||||
bpy.ops.object.material_slot_select()
|
||||
except:
|
||||
print('material wasn\'t found: ' + mat)
|
||||
bpy.ops.mesh.separate(type='SELECTED')
|
||||
|
||||
eye_list = ['KK EyeR (hitomi) ' + c.get_name(),
|
||||
'KK EyeL (hitomi) ' + c.get_name(),
|
||||
'KK Eyewhites (sirome) ' + c.get_name(),
|
||||
'KK Eyeline up ' + c.get_name(),
|
||||
'KK Eyeline down ' + c.get_name()]
|
||||
separateMaterial(eye_list)
|
||||
|
||||
eyes = bpy.data.objects[body.name + '.001']
|
||||
eyes.name = 'Eyes'
|
||||
if eyes.modifiers.get('Outline Modifier'):
|
||||
eyes.modifiers['Outline Modifier'].show_viewport = False
|
||||
eyes.modifiers['Outline Modifier'].show_render = False
|
||||
|
||||
#do the same for the eyebrows
|
||||
separateMaterial(['KK Eyebrows (mayuge) ' + c.get_name()])
|
||||
eyebrows = bpy.data.objects[body.name + '.001']
|
||||
eyebrows.name = 'Eyebrows'
|
||||
if eyebrows.modifiers.get('Outline Modifier'):
|
||||
eyebrows.modifiers['Outline Modifier'].show_viewport = False
|
||||
eyebrows.modifiers['Outline Modifier'].show_render = False
|
||||
|
||||
bpy.ops.object.mode_set(mode = 'OBJECT')
|
||||
link_keys(body, [eyes, eyebrows])
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
Reference in New Issue
Block a user