Merge branch 'main' into viseme-dev

This commit is contained in:
Yusarina
2024-07-25 00:57:08 +01:00
committed by GitHub
18 changed files with 712 additions and 200 deletions
+60 -2
View File
@@ -1,8 +1,12 @@
import bpy
import numpy as np
from .dictionaries import bone_names
import threading
import time
import webbrowser
import typing
from typing import List, Optional
from typing import List, Optional, Tuple
from bpy.types import Object, ShapeKey, Mesh, Context
from functools import lru_cache
@@ -13,7 +17,6 @@ def clean_material_names(mesh: Mesh) -> None:
mesh.active_material_index = j
mesh.active_material.name = mat.name[:-len(mat.name.rstrip('0')) - 1]
# This will fix faulty uv coordinates, cats did this a other way which can have unintended consequences,
# this is the best way i could of think of doing this for the time being, however may need improvements.
@@ -57,6 +60,61 @@ def get_armature(context: Context, armature_name: Optional[str] = None) -> Optio
if obj.type == "ARMATURE":
return obj
return next((obj for obj in context.view_layer.objects if obj.type == 'ARMATURE'), None)
def get_armatures(self, context: Context) -> List[Tuple[str, str, str]]:
return [(obj.name, obj.name, "") for obj in bpy.data.objects if obj.type == 'ARMATURE']
def get_selected_armature(context: Context) -> Optional[Object]:
if context.scene.selected_armature:
armature = bpy.data.objects.get(context.scene.selected_armature)
if is_valid_armature(armature):
return armature
return None
def set_selected_armature(context: Context, armature: Optional[Object]) -> None:
context.scene.selected_armature = armature.name if armature else ""
def is_valid_armature(armature: Object) -> bool:
if not armature or armature.type != 'ARMATURE':
return False
if not armature.data or not armature.data.bones:
return False
return True
def select_current_armature(context: Context) -> bool:
armature = get_selected_armature(context)
if armature:
bpy.ops.object.select_all(action='DESELECT')
armature.select_set(True)
context.view_layer.objects.active = armature
return True
return False
def get_all_meshes(context: Context) -> List[Object]:
armature = get_selected_armature(context)
if armature and is_valid_armature(armature):
return [obj for obj in bpy.data.objects if obj.type == 'MESH' and obj.parent == armature]
return []
def open_web_after_delay_multi_threaded(delay: typing.Optional[float] = 1.0, url: typing.Union[str, typing.Any] = ""):
thread = threading.Thread(target=open_web_after_delay,args=[delay,url],name="open_browser_thread")
thread.start()
def open_web_after_delay(delay, url):
print("opening browser in "+str(delay)+" seconds.")
time.sleep(delay)
webbrowser.open_new_tab(url)
def duplicatebone(b: bpy.types.EditBone) -> bpy.types.EditBone:
arm = bpy.context.object.data
cb = arm.edit_bones.new(b.name)
cb.head = b.head
cb.tail = b.tail
cb.matrix = b.matrix
cb.parent = b.parent
return cb
def has_shapekeys(mesh_obj: Object) -> bool:
return mesh_obj.data.shape_keys is not None
+52 -52
View File
@@ -5,85 +5,85 @@
# Note from @989onan: Please make sure to make your names are lowercase in this array. I banged my head metaphorically till I figured that out...
# Taken from Tuxedo/Cats
bone_names = {
"right_shoulder": ["rightshoulder", "shoulderr", "rshoulder"],
"right_arm": ["rightarm", "armr", "rarm", "upperarmr", "rupperarm", "rightupperarm", "upperarmright", "uparmr", "ruparm"],
"right_elbow": ["rightelbow", "elbowr", "relbow", "lowerarmr", "rightlowerarm", "lowerarmr","rlowerarm", "lowerarmright", "lowarmr", "rlowarm", "forearmr","rforearm"],
"right_wrist": ["rightwrist", "wristr", "rwrist", "handr", "righthand", "rhand"],
"right_shoulder": ["rightshoulder", "shoulderr", "rshoulder", "valvebipedbip01rclavicle"],
"right_arm": ["rightarm", "armr", "rarm", "upperarmr", "rupperarm", "rightupperarm", "uparmr", "ruparm", "valvebipedbip01rupperarm"],
"right_elbow": ["rightelbow", "elbowr", "relbow", "lowerarmr", "rightlowerarm", "lowerarmr","rlowerarm", "lowarmr", "rlowarm", "forearmr","rforearm", "valvebipedbip01rforearm"],
"right_wrist": ["rightwrist", "wristr", "rwrist", "handr", "righthand", "rhand", "valvebipedbip01rhand"],
#hand l fingers
"pinkie_0_r": ["littlefinger0r","pinkie0r","rpinkie0","pinkiemetacarpalr"],
"pinkie_1_r": ["littlefinger1r","pinkie1r","rpinkie1","pinkieproximalr"],
"pinkie_2_r": ["littlefinger2r","pinkie2r","rpinkie2","pinkieintermediater"],
"pinkie_3_r": ["littlefinger3r","pinkie3r","rpinkie3","pinkiedistalr"],
"pinkie_1_r": ["littlefinger1r","pinkie1r","rpinkie1","pinkieproximalr", "valvebipedbip01rfinger4"],
"pinkie_2_r": ["littlefinger2r","pinkie2r","rpinkie2","pinkieintermediater", "valvebipedbip01rfinger41"],
"pinkie_3_r": ["littlefinger3r","pinkie3r","rpinkie3","pinkiedistalr", "valvebipedbip01rfinger42"],
"ring_0_r": ["ringfinger0r","ring0r","rring0","ringmetacarpalr"],
"ring_1_r": ["ringfinger1r","ring1r","rring1","ringproximalr"],
"ring_2_r": ["ringfinger2r","ring2r","rring2","ringintermediater"],
"ring_3_r": ["ringfinger3r","ring3r","rring3","ringdistalr"],
"ring_1_r": ["ringfinger1r","ring1r","rring1","ringproximalr", "valvebipedbip01rfinger3"],
"ring_2_r": ["ringfinger2r","ring2r","rring2","ringintermediater", "valvebipedbip01rfinger31"],
"ring_3_r": ["ringfinger3r","ring3r","rring3","ringdistalr", "valvebipedbip01rfinger32"],
"middle_0_r": ["middlefinger0r","middle0r","rmiddle0","middlemetacarpalr"],
"middle_1_r": ["middlefinger1r","middle1r","rmiddle1","middleproximalr"],
"middle_2_r": ["middlefinger2r","middle2r","rmiddle2","middleintermediater"],
"middle_3_r": ["middlefinger3r","middle3r","rmiddle3","middledistalr"],
"middle_1_r": ["middlefinger1r","middle1r","rmiddle1","middleproximalr", "valvebipedbip01rfinger2"],
"middle_2_r": ["middlefinger2r","middle2r","rmiddle2","middleintermediater", "valvebipedbip01rfinger21"],
"middle_3_r": ["middlefinger3r","middle3r","rmiddle3","middledistalr", "valvebipedbip01rfinger22"],
"index_0_r": ["indexfinger0r","index0r","rindex0","indexmetacarpalr"],
"index_1_r": ["indexfinger1r","index1r","rindex1","indexproximalr"],
"index_2_r": ["indexfinger2r","index2r","rindex2","indexintermediater"],
"index_3_r": ["indexfinger3r","index3r","rindex3","indexdistalr"],
"index_1_r": ["indexfinger1r","index1r","rindex1","indexproximalr", "valvebipedbip01rfinger1"],
"index_2_r": ["indexfinger2r","index2r","rindex2","indexintermediater", "valvebipedbip01rfinger11"],
"index_3_r": ["indexfinger3r","index3r","rindex3","indexdistalr", "valvebipedbip01rfinger12"],
"thumb_0_r": ["thumb0r","rthumb0","thumbmetacarpalr"],
"thumb_1_r": ['thumb1r',"rthumb1","thumbproximalr"],
"thumb_2_r": ['thumb2r',"rthumb2","thumbintermediater"],
"thumb_3_r": ['thumb3r',"rthumb3","thumbdistalr"],
"thumb_1_r": ['thumb1r',"rthumb1","thumbproximalr", "valvebipedbip01rfinger0"],
"thumb_2_r": ['thumb2r',"rthumb2","thumbintermediater", "valvebipedbip01rfinger01"],
"thumb_3_r": ['thumb3r',"rthumb3","thumbdistalr", "valvebipedbip01rfinger02"],
"right_leg": ["rightleg", "legr", "rleg", "upperlegr", "rupperleg", "thighr", "rightupperleg", "upperlegright", "uplegr", "rupleg"],
"right_knee": ["rightknee", "kneer", "rknee", "lowerlegr", "calfr", "rlowerleg", "rcalf", "rightlowerleg", "lowerlegright", "lowlegr", "rlowleg"],
"right_ankle": ["rightankle", "ankler", "rankle", "footright", "footr", "rfoot", "rightfoot", "rightfeet", "feetright", "rfeet", "feetr"],
"right_toe": ["righttoe", "toeright", "toer", "rtoe", "toesr", "rtoes"],
"right_leg": ["rightleg", "legr", "rleg", "upperlegr", "rupperleg", "thighr", "rightupperleg", "uplegr", "rupleg", "valvebipedbip01rthigh"],
"right_knee": ["rightknee", "kneer", "rknee", "lowerlegr", "calfr", "rlowerleg", "rcalf", "rightlowerleg", "lowlegr", "rlowleg", "valvebipedbip01rcalf"],
"right_ankle": ["rightankle", "ankler", "rankle", "rightfoot", "footr", "rfoot", "rightfoot", "rightfeet", "feetright", "rfeet", "feetr", "valvebipedbip01rfoot"],
"right_toe": ["righttoe", "toeright", "toer", "rtoe", "toesr", "rtoes", "valvebipedbip01rtoe0"],
"left_shoulder": ["leftshoulder", "shoulderl", "lshoulder"],
"left_arm": ["leftarm", "arml", "rarm", "upperarml", "lupperarm", "leftupperarm", "upperarmleft", "uparml", "luparm"],
"left_elbow": ["leftelbow", "elbowl", "lelbow", "lowerarml", "leftlowerarm", "lowerarmleft", "lowerarml", "llowerarm", "lowarml", "llowarm", "forearml","lforearm"],
"left_wrist": ["leftwrist", "wristl", "lwrist", "handl", "lefthand", "lhand"],
"left_shoulder": ["leftshoulder", "shoulderl", "lshoulder", "valvebipedbip01lclavicle"],
"left_arm": ["leftarm", "arml", "rarm", "upperarml", "lupperarm", "leftupperarm", "uparml", "luparm", "valvebipedbip01lupperarm"],
"left_elbow": ["leftelbow", "elbowl", "lelbow", "lowerarml", "leftlowerarm", "lowerarml", "llowerarm", "lowarml", "llowarm", "forearml","lforearm", "valvebipedbip01lforearm"],
"left_wrist": ["leftwrist", "wristl", "lwrist", "handl", "lefthand", "lhand", "valvebipedbip01lhand"],
#hand l fingers
"pinkie_0_l": ["pinkiefinger0l","pinkie0l","lpinkie0","pinkiemetacarpall"],
"pinkie_1_l": ["littlefinger1l","pinkie1l","lpinkie1","pinkieproximall"],
"pinkie_2_l": ["littlefinger2l","pinkie2l","lpinkie2","pinkieintermediatel"],
"pinkie_3_l": ["littlefinger3l","pinkie3l","lpinkie3","pinkiedistall"],
"pinkie_1_l": ["littlefinger1l","pinkie1l","lpinkie1","pinkieproximall", "valvebipedbip01lfinger4"],
"pinkie_2_l": ["littlefinger2l","pinkie2l","lpinkie2","pinkieintermediatel", "valvebipedbip01lfinger41"],
"pinkie_3_l": ["littlefinger3l","pinkie3l","lpinkie3","pinkiedistall", "valvebipedbip01lfinger42"],
"ring_0_l": ["ringfinger0l","ring0l","lring0","ringmetacarpall"],
"ring_1_l": ["ringfinger1l","ring1l","lring1","ringproximall"],
"ring_2_l": ["ringfinger2l","ring2l","lring2","ringintermediatel"],
"ring_3_l": ["ringfinger3l","ring3l","lring3","ringdistall"],
"ring_1_l": ["ringfinger1l","ring1l","lring1","ringproximall", "valvebipedbip01lfinger3"],
"ring_2_l": ["ringfinger2l","ring2l","lring2","ringintermediatel", "valvebipedbip01lfinger31"],
"ring_3_l": ["ringfinger3l","ring3l","lring3","ringdistall", "valvebipedbip01lfinger32"],
"middle_0_l": ["middlefinger0l","middle_0l","lmiddle0","middlemetacarpall"],
"middle_1_l": ["middlefinger1l","middle_1l","lmiddle1","middleproximall"],
"middle_2_l": ["middlefinger2l","middle_2l","lmiddle2","middleintermediatel"],
"middle_3_l": ["middlefinger3l","middle_3l","lmiddle3","middledistall"],
"middle_1_l": ["middlefinger1l","middle_1l","lmiddle1","middleproximall", "valvebipedbip01lfinger2"],
"middle_2_l": ["middlefinger2l","middle_2l","lmiddle2","middleintermediatel", "valvebipedbip01lfinger21"],
"middle_3_l": ["middlefinger3l","middle_3l","lmiddle3","middledistall", "valvebipedbip01lfinger22"],
"index_0_l": ["indexfinger0l","index0l","lindex0","indexmetacarpall"],
"index_1_l": ["indexfinger1l","index1l","lindex1","indexproximall"],
"index_2_l": ["indexfinger2l","index2l","lindex2","indexintermediatel"],
"index_3_l": ["indexfinger3l","index3l","lindex3","indexdistall"],
"index_1_l": ["indexfinger1l","index1l","lindex1","indexproximall", "valvebipedbip01lfinger1"],
"index_2_l": ["indexfinger2l","index2l","lindex2","indexintermediatel", "valvebipedbip01lfinger11"],
"index_3_l": ["indexfinger3l","index3l","lindex3","indexdistall", "valvebipedbip01lfinger12"],
"thumb_0_l": ["thumb0l","lthumb0","thumbmetacarpall"],
"thumb_1_l": ['thumb1l',"lthumb1","thumbproximall"],
"thumb_2_l": ['thumb2l',"lthumb2","thumbintermediatel"],
"thumb_3_l": ['thumb3l',"lthumb3","thumbdistall"],
"thumb_1_l": ['thumb1l',"lthumb1","thumbproximall", "valvebipedbip01lfinger0"],
"thumb_2_l": ['thumb2l',"lthumb2","thumbintermediatel", "valvebipedbip01lfinger01"],
"thumb_3_l": ['thumb3l',"lthumb3","thumbdistall", "valvebipedbip01lfinger02"],
"left_leg": ["leftleg", "legl", "lleg", "upperlegl", "lupperleg", "thighl", "leftupperleg", "upperlegleft", "uplegl", "lupleg"],
"left_knee": ["leftknee", "kneel", "lknee", "lowerlegl", "llowerleg", "calfl", "lcalf", "leftlowerleg", "lowerlegleft", 'lowlegl', 'llowleg'],
"left_ankle": ["leftankle", "anklel", "rankle", "footleft", "footl", "lfoot", "leftfoot", "leftfeet", "feetleft", "lfeet", "feetl"],
"left_toe": ["lefttoe", "toeleft", "toel", "ltoe", "toesl", "ltoes"],
"left_leg": ["leftleg", "legl", "lleg", "upperlegl", "lupperleg", "thighl", "leftupperleg", "uplegl", "lupleg", "valvebipedbip01lthigh"],
"left_knee": ["leftknee", "kneel", "lknee", "lowerlegl", "llowerleg", "calfl", "lcalf", "leftlowerleg", 'lowlegl', 'llowleg', "valvebipedbip01lcalf"],
"left_ankle": ["leftankle", "anklel", "rankle", "leftfoot", "footl", "lfoot", "leftfoot", "leftfeet", "feetleft", "lfeet", "feetl", "valvebipedbip01lfoot"],
"left_toe": ["lefttoe", "toeleft", "toel", "ltoe", "toesl", "ltoes", "valvebipedbip01ltoe0"],
"hips": ["pelvis", "hips", "hip"],
"spine": ["torso", "spine"],
"chest": ["chest"],
"upper_chest": ["upperchest", "chestupper"],
"neck": ["neck"],
"head": ["head", "cabeza"],
"hips": ["pelvis", "hips", "valvebipedbip01pelvis"],
"spine": ["torso", "spine", "valvebipedbip01spine"],
"chest": ["chest", "valvebipedbip01spine1"],
"upper_chest": ["upperchest", "valvebipedbip01spine4"],
"neck": ["neck", "valvebipedbip01neck1"],
"head": ["head", "valvebipedbip01head1"],
"left_eye": ["eyeleft", "lefteye", "eyel", "leye"],
"right_eye": ["eyeright", "righteye", "eyer", "reye"],
}
+48 -12
View File
@@ -1,17 +1,53 @@
import bpy
# Importers which don't need much code should be added here, however if a importer needs alot of code
# Like the PMX and PMD importers, they should be added to their own files.
# Like the PMX and PMD importers, they should be added to their own files and referenced in the import_types str->lambda dictionary.
#See below comments on how the system works. - @989onan
# FBX Importer settings borrowed form Cat's Blender Plugin
def import_fbx(filepath):
try:
bpy.ops.import_scene.fbx(
filepath=filepath,
automatic_bone_orientation=False,
use_prepost_rot=False,
use_anim=False
)
except (TypeError, ValueError) as e:
print(f"Error importing FBX: {str(e)}")
import importlib.util
import os
import typing
from .import_pmx import import_pmx
from .import_pmd import import_pmd
if importlib.util.find_spec("io_scene_valvesource") is not None:
#from .....scripts.addons.io_scene_valvesource.import_smd import SmdImporter #<- use this to check if your IDE is working properly. idfk
from io_scene_valvesource.import_smd import SmdImporter #ignore IDE bitching this is fine, trust me, also above comment should be okay to an IDE usually if set up right. ^_^ - @989onan
def import_multi_files(method = None, directory: typing.Optional[str] = None, files: list[dict[str,str]] = None, filepath: typing.Optional[str] = ""):
if not files:
method(directory, filepath)
else:
for file in files:
fullpath = os.path.join(directory,os.path.basename(file["name"]))
print("run method!")
method(directory, fullpath)
#each import should map to a type. even in the case that multiple methods should import together, or have the same import method. Make sure the lambdas match so they get grouped together
#In the case of a file importer that takes only one file argument and each one needs individual import, use above method. (example of it in use is ".dae" format)
import_types: dict[str, typing.Callable[[str, list[dict[str,str]], str], None]] = {
"fbx": (lambda directory, files, filepath : bpy.ops.import_scene.fbx(files=files, directory=directory, filepath=filepath,automatic_bone_orientation=False,use_prepost_rot=False,use_anim=False)),
"smd": (lambda directory, files, filepath : eval("bpy."+SmdImporter.bl_idname+".(files=files, directory=directory, filepath=filepath)")),
"dmx": (lambda directory, files, filepath: eval("bpy."+SmdImporter.bl_idname+".(files=files, directory=directory, filepath=filepath)")),
"gltf": (lambda directory, files, filepath : bpy.ops.import_scene.gltf(files=files, filepath=filepath)),
"glb": (lambda directory, files, filepath : bpy.ops.import_scene.gltf(files=files, filepath=filepath)),
"qc": (lambda directory, files, filepath : eval("bpy."+SmdImporter.bl_idname+".(files=files, directory=directory, filepath=filepath)")),
"obj": (lambda directory, files, filepath : bpy.ops.wm.obj_import(files=files, directory=directory, filepath=filepath)),
"dae": (lambda directory, files, filepath : import_multi_files(directory=directory, files=files, filepath=filepath, method = (lambda directory, filepath: bpy.ops.wm.collada_import(filepath=filepath, auto_connect = True, find_chains = True, fix_orientation = True)))),
"3ds": (lambda directory, files, filepath : bpy.ops.import_scene.max3ds(files=files, directory=directory, filepath=filepath)),
"stl": (lambda directory, files, filepath : bpy.ops.import_mesh.stl(files=files, directory=directory, filepath=filepath)),
"mtl": (lambda directory, files, filepath : bpy.ops.wm.obj_import(files=files, directory=directory, filepath=filepath)),
"x3d": (lambda directory, files, filepath : bpy.ops.import_scene.x3d(files=files, directory=directory, filepath=filepath)),
"wrl": (lambda directory, files, filepath : bpy.ops.import_scene.x3d(files=files, directory=directory, filepath=filepath)),
"vmd": (lambda directory, files, filepath : import_multi_files(directory=directory, files=files, filepath=filepath, method = (lambda directory, filepath: bpy.ops.tuxedo.import_mmd_animation(directory=directory, filepath=filepath)))),
"pmx": (lambda directory, files, filepath : import_pmx(filepath)),
"pmd": (lambda directory, files, filepath : import_pmd(filepath)),
}
def concat_imports_filter(imports):
names = ""
for importer in imports.keys():
names = names+"*."+importer+";"
return names
imports = concat_imports_filter(import_types)
+3
View File
@@ -0,0 +1,3 @@
{
"language": 0
}
+12
View File
@@ -1,6 +1,8 @@
import bpy
from ..functions.translations import t, get_languages_list, update_language
from ..core.addon_preferences import get_preference
from .common import get_armatures
def register() -> None:
default_language = get_preference("language", 0)
@@ -35,6 +37,12 @@ def register() -> None:
max=2.0
)
bpy.types.Scene.selected_armature = bpy.props.EnumProperty(
items=get_armatures,
name="Selected Armature",
description="The currently selected armature for Avatar Toolkit operations"
)
def unregister() -> None:
if hasattr(bpy.types.Scene, "avatar_toolkit_language"):
del bpy.types.Scene.avatar_toolkit_language
@@ -53,3 +61,7 @@ def unregister() -> None:
if hasattr(bpy.types.Scene, "shape_intensity"):
del bpy.types.Scene.shape_intensity
if hasattr(bpy.types.Scene, "selected_armature"):
del bpy.types.Scene.selected_armature
+1 -1
View File
@@ -49,7 +49,7 @@ def toposort(deps_dict):
unsorted.append(value)
deps_dict = {value : deps_dict[value] - sorted_values for value in unsorted}
sort_order(sorted_list) #to sort by 'bl_order' so we can choose how things may appear in the ui
#sort_order(sorted_list) #to sort by 'bl_order' so we can choose how things may appear in the ui
return sorted_list