Merge pull request #44 from 989onan/cleanup

More cleanup
This commit is contained in:
Yusarina
2024-09-11 01:33:17 +01:00
committed by GitHub
20 changed files with 122 additions and 139 deletions
+8 -8
View File
@@ -21,7 +21,7 @@ class SceneMatClass(PropertyGroup):
register_class(SceneMatClass) register_class(SceneMatClass)
class material_list_bool: class MaterialListBool:
#For the love that is holy do not ever touch these. If this was java I would make these private #For the love that is holy do not ever touch these. If this was java I would make these private
#They should only be accessed via context.scene.texture_atlas_Has_Mat_List_Shown #They should only be accessed via context.scene.texture_atlas_Has_Mat_List_Shown
#This is so we know if the materials are up to date. messing with these variables directly will make the thing blow up. #This is so we know if the materials are up to date. messing with these variables directly will make the thing blow up.
@@ -31,9 +31,9 @@ class material_list_bool:
bool_material_list_expand: dict[str,bool] = {} bool_material_list_expand: dict[str,bool] = {}
def set_bool(self, value: bool) -> None: def set_bool(self, value: bool) -> None:
material_list_bool.bool_material_list_expand[bpy.context.scene.name] = value MaterialListBool.bool_material_list_expand[bpy.context.scene.name] = value
if value == False: if value == False:
material_list_bool.old_list[bpy.context.scene.name] = [] MaterialListBool.old_list[bpy.context.scene.name] = []
def get_bool(self) -> bool: def get_bool(self) -> bool:
newlist: list[Material] = [] newlist: list[Material] = []
@@ -45,20 +45,20 @@ class material_list_bool:
newlist.append(mat_slot.material) newlist.append(mat_slot.material)
still_the_same: bool = True still_the_same: bool = True
if bpy.context.scene.name in material_list_bool.old_list: if bpy.context.scene.name in MaterialListBool.old_list:
for item in newlist: for item in newlist:
if item not in material_list_bool.old_list[bpy.context.scene.name]: if item not in MaterialListBool.old_list[bpy.context.scene.name]:
still_the_same = False still_the_same = False
break break
for item in material_list_bool.old_list[bpy.context.scene.name]: for item in MaterialListBool.old_list[bpy.context.scene.name]:
if item not in newlist: if item not in newlist:
still_the_same = False still_the_same = False
break break
else: else:
still_the_same = False still_the_same = False
material_list_bool.bool_material_list_expand[bpy.context.scene.name] = still_the_same MaterialListBool.bool_material_list_expand[bpy.context.scene.name] = still_the_same
return material_list_bool.bool_material_list_expand[bpy.context.scene.name] return MaterialListBool.bool_material_list_expand[bpy.context.scene.name]
### Clean up material names in the given mesh by removing the '.001' suffix. ### Clean up material names in the given mesh by removing the '.001' suffix.
+1 -1
View File
@@ -9,7 +9,7 @@ from ..functions.translations import t
@register_wrap @register_wrap
class ExportResonite(Operator): class AvatarToolKit_OT_ExportResonite(Operator):
bl_idname = 'avatar_toolkit.export_resonite' bl_idname = 'avatar_toolkit.export_resonite'
bl_label = t("Importer.export_resonite.label") bl_label = t("Importer.export_resonite.label")
bl_description = t("Importer.export_resonite.desc") bl_description = t("Importer.export_resonite.desc")
+3 -3
View File
@@ -4,7 +4,7 @@ from ..core.register import register_property
from bpy.types import Scene, Object, Material, Context from bpy.types import Scene, Object, Material, Context
from bpy.props import BoolProperty, EnumProperty, IntProperty, CollectionProperty, StringProperty, FloatVectorProperty, PointerProperty from bpy.props import BoolProperty, EnumProperty, IntProperty, CollectionProperty, StringProperty, FloatVectorProperty, PointerProperty
from ..core.addon_preferences import get_preference from ..core.addon_preferences import get_preference
from ..core.common import SceneMatClass, material_list_bool, get_armatures, get_mesh_items from ..core.common import SceneMatClass, MaterialListBool, get_armatures, get_mesh_items
def register() -> None: def register() -> None:
default_language = get_preference("language", 0) default_language = get_preference("language", 0)
@@ -106,8 +106,8 @@ def register() -> None:
register_property((Scene, "texture_atlas_Has_Mat_List_Shown", BoolProperty( register_property((Scene, "texture_atlas_Has_Mat_List_Shown", BoolProperty(
default=False, default=False,
get=material_list_bool.get_bool, get=MaterialListBool.get_bool,
set=material_list_bool.set_bool))) set=MaterialListBool.set_bool)))
def unregister() -> None: def unregister() -> None:
+1 -1
View File
@@ -5,7 +5,7 @@ from ..core.common import get_selected_armature, is_valid_armature, get_all_mesh
from ..functions.translations import t from ..functions.translations import t
@register_wrap @register_wrap
class ApplyTransforms(Operator): class AvatarToolKit_OT_ApplyTransforms(Operator):
bl_idname = "avatar_toolkit.apply_transforms" bl_idname = "avatar_toolkit.apply_transforms"
bl_label = t("Tools.apply_transforms.label") bl_label = t("Tools.apply_transforms.label")
bl_description = t("Tools.apply_transforms.desc") bl_description = t("Tools.apply_transforms.desc")
+2 -4
View File
@@ -2,13 +2,11 @@ from pathlib import Path
import numpy import numpy
import bpy import bpy
import re
import os import os
from typing import List, Tuple, Optional from typing import List, Tuple, Optional
from mathutils import Vector
from bpy.types import Material, Operator, Context, Object, Image, Mesh, MeshUVLoopLayer, Float2AttributeValue, ShaderNodeTexImage, ShaderNodeBsdfPrincipled, ShaderNodeNormalMap from bpy.types import Material, Operator, Context, Object, Image, Mesh, MeshUVLoopLayer, Float2AttributeValue, ShaderNodeTexImage, ShaderNodeBsdfPrincipled, ShaderNodeNormalMap
from ..core.register import register_wrap from ..core.register import register_wrap
from ..core.common import SceneMatClass, material_list_bool from ..core.common import SceneMatClass, MaterialListBool
from ..core.packer.rectangle_packer import MaterialImageList, BinPacker from ..core.packer.rectangle_packer import MaterialImageList, BinPacker
from ..functions.translations import t from ..functions.translations import t
@@ -113,7 +111,7 @@ def prep_images_in_scene(context: Context) -> list[MaterialImageList]:
@register_wrap @register_wrap
class Atlas_Materials(Operator): class AvatarToolKit_OT_AtlasMaterials(Operator):
bl_idname = "avatar_toolkit.atlas_materials" bl_idname = "avatar_toolkit.atlas_materials"
bl_label = t("TextureAtlas.atlas_materials") bl_label = t("TextureAtlas.atlas_materials")
+1 -1
View File
@@ -53,7 +53,7 @@ def get_base_name(name: str) -> str:
return mat_match.group(1) if mat_match else name return mat_match.group(1) if mat_match else name
@register_wrap @register_wrap
class CombineMaterials(Operator): class AvatarToolKit_OT_CombineMaterials(Operator):
bl_idname = "avatar_toolkit.combine_materials" bl_idname = "avatar_toolkit.combine_materials"
bl_label = t("Optimization.combine_materials.label") bl_label = t("Optimization.combine_materials.label")
bl_description = t("Optimization.combine_materials.desc") bl_description = t("Optimization.combine_materials.desc")
+2 -2
View File
@@ -6,8 +6,8 @@ import re
@register_wrap @register_wrap
class CreateDigitigradeLegs(bpy.types.Operator): class AvatarToolKit_OT_CreateDigitigradeLegs(bpy.types.Operator):
bl_idname = "avatar_toolkit.createdigitigradelegs" bl_idname = "avatar_toolkit.create_digitigrade_legs"
bl_label = t('Tools.create_digitigrade_legs.label') bl_label = t('Tools.create_digitigrade_legs.label')
bl_description = t('Tools.create_digitigrade_legs.desc') bl_description = t('Tools.create_digitigrade_legs.desc')
+5 -6
View File
@@ -3,14 +3,13 @@ from bpy.types import Operator
from bpy_extras.io_utils import ImportHelper from bpy_extras.io_utils import ImportHelper
from ..core.register import register_wrap from ..core.register import register_wrap
from ..core.importer import imports, import_types from ..core.importer import imports, import_types
from ..core.common import remove_default_objects from ..core.common import remove_default_objects, open_web_after_delay_multi_threaded
from ..functions.translations import t from ..functions.translations import t
import pathlib import pathlib
import os import os
from ..core import common
@register_wrap @register_wrap
class ImportAnyModel(Operator, ImportHelper): class AvatarToolKit_OT_ImportAnyModel(Operator, ImportHelper):
bl_idname = 'avatar_toolkit.import_any_model' bl_idname = 'avatar_toolkit.import_any_model'
bl_label = t('Tools.import_any_model.label') bl_label = t('Tools.import_any_model.label')
bl_description = t('Tools.import_any_model.desc') bl_description = t('Tools.import_any_model.desc')
@@ -24,7 +23,7 @@ class ImportAnyModel(Operator, ImportHelper):
#since I wrote this myself, a bit more efficent than cats. mostly - @989onan #since I wrote this myself, a bit more efficent than cats. mostly - @989onan
def execute(self, context: bpy.types.Context): def execute(self, context: bpy.types.Context):
file_grouping_dict: dict[str, list[dict[str,str]]] = dict()#group our files so our importers can import them together. in the case of OBJ+MTL and others that need grouped files, this is extremely important. file_grouping_dict: dict[str, list[dict[str,str]]] = dict()#group our files so our importers can import them together. in the case of OBJ+MTL and others that need grouped files, this is extremely important.
common.remove_default_objects() remove_default_objects()
#check if we are importing multiple files #check if we are importing multiple files
is_multi = False is_multi = False
try: try:
@@ -69,9 +68,9 @@ class ImportAnyModel(Operator, ImportHelper):
else: else:
import_types[file_group_name]("",files,self.filepath) #give an empty directory, works just fine for 90% import_types[file_group_name]("",files,self.filepath) #give an empty directory, works just fine for 90%
except AttributeError as e: except AttributeError as e:
print("Warning, you may not have the required importer!") print("Warning, you may not have the required importer for extension type \"{extension}\"!".format(extension = file_group_name))
common.open_web_after_delay_multi_threaded(delay=12, url=t('Importing.importer_search_term').format(extension = file_group_name)) open_web_after_delay_multi_threaded(delay=12, url=t('Importing.importer_search_term').format(extension = file_group_name))
self.report({'ERROR'},t('Importing.need_importer').format(extension = file_group_name)) self.report({'ERROR'},t('Importing.need_importer').format(extension = file_group_name))
+2 -2
View File
@@ -6,7 +6,7 @@ from ..core.common import fix_uv_coordinates, get_selected_armature, is_valid_ar
from ..functions.translations import t from ..functions.translations import t
@register_wrap @register_wrap
class JoinAllMeshes(Operator): class AvatarToolKit_OT_JoinAllMeshes(Operator):
bl_idname = "avatar_toolkit.join_all_meshes" bl_idname = "avatar_toolkit.join_all_meshes"
bl_label = t("Optimization.join_all_meshes.label") bl_label = t("Optimization.join_all_meshes.label")
bl_description = t("Optimization.join_all_meshes.desc") bl_description = t("Optimization.join_all_meshes.desc")
@@ -72,7 +72,7 @@ class JoinAllMeshes(Operator):
finish_progress(context) finish_progress(context)
@register_wrap @register_wrap
class JoinSelectedMeshes(Operator): class AvatarToolKit_OT_JoinSelectedMeshes(Operator):
bl_idname = "avatar_toolkit.join_selected_meshes" bl_idname = "avatar_toolkit.join_selected_meshes"
bl_label = t("Optimization.join_selected_meshes.label") bl_label = t("Optimization.join_selected_meshes.label")
bl_description = t("Optimization.join_selected_meshes.desc") bl_description = t("Optimization.join_selected_meshes.desc")
+2 -2
View File
@@ -12,7 +12,7 @@ class meshEntry(TypedDict):
cur_vertex_pass: int cur_vertex_pass: int
@register_wrap @register_wrap
class RemoveDoublesSafelyAdvanced(Operator): class AvatarToolKit_OT_RemoveDoublesSafelyAdvanced(Operator):
bl_idname = "avatar_toolkit.remove_doubles_safely_advanced" bl_idname = "avatar_toolkit.remove_doubles_safely_advanced"
bl_label = t("Optimization.remove_doubles_safely_advanced.label") bl_label = t("Optimization.remove_doubles_safely_advanced.label")
bl_description = t("Optimization.remove_doubles_safely_advanced.desc") bl_description = t("Optimization.remove_doubles_safely_advanced.desc")
@@ -30,7 +30,7 @@ class RemoveDoublesSafelyAdvanced(Operator):
bpy.ops.avatar_toolkit.remove_doubles_safely('INVOKE_DEFAULT',advanced=True,merge_distance=self.merge_distance) bpy.ops.avatar_toolkit.remove_doubles_safely('INVOKE_DEFAULT',advanced=True,merge_distance=self.merge_distance)
return {'FINISHED'} return {'FINISHED'}
@register_wrap @register_wrap
class RemoveDoublesSafely(Operator): class AvatarToolKit_OT_RemoveDoublesSafely(Operator):
bl_idname = "avatar_toolkit.remove_doubles_safely" bl_idname = "avatar_toolkit.remove_doubles_safely"
bl_label = t("Optimization.remove_doubles_safely.label") bl_label = t("Optimization.remove_doubles_safely.label")
bl_description = t("Optimization.remove_doubles_safely.desc") bl_description = t("Optimization.remove_doubles_safely.desc")
+1 -1
View File
@@ -8,7 +8,7 @@ from ..core.common import get_selected_armature, simplify_bonename, is_valid_arm
from ..functions.translations import t from ..functions.translations import t
@register_wrap @register_wrap
class ConvertToResonite(Operator): class AvatarToolKit_OT_ConvertToResonite(Operator):
bl_idname = 'avatar_toolkit.convert_to_resonite' bl_idname = 'avatar_toolkit.convert_to_resonite'
bl_label = t('Tools.convert_to_resonite.label') bl_label = t('Tools.convert_to_resonite.label')
bl_description = t('Tools.convert_to_resonite.desc') bl_description = t('Tools.convert_to_resonite.desc')
+2 -3
View File
@@ -1,11 +1,10 @@
import bpy import bpy
from bpy.types import Context, Operator from bpy.types import Context, Operator
from ..core.register import register_wrap from ..core.register import register_wrap
from ..core.common import get_selected_armature, is_valid_armature, select_current_armature
from ..functions.translations import t from ..functions.translations import t
@register_wrap @register_wrap
class SeparateByMaterials(Operator): class AvatarToolKit_OT_SeparateByMaterials(Operator):
bl_idname = "avatar_toolkit.separate_by_materials" bl_idname = "avatar_toolkit.separate_by_materials"
bl_label = t("Tools.separate_by_materials.label") bl_label = t("Tools.separate_by_materials.label")
bl_description = t("Tools.separate_by_materials.desc") bl_description = t("Tools.separate_by_materials.desc")
@@ -25,7 +24,7 @@ class SeparateByMaterials(Operator):
return {'FINISHED'} return {'FINISHED'}
@register_wrap @register_wrap
class SeparateByLooseParts(Operator): class AvatarToolKit_OT_SeparateByLooseParts(Operator):
bl_idname = "avatar_toolkit.separate_by_loose_parts" bl_idname = "avatar_toolkit.separate_by_loose_parts"
bl_label = t("Tools.separate_by_loose_parts.label") bl_label = t("Tools.separate_by_loose_parts.label")
bl_description = t("Tools.separate_by_loose_parts.desc") bl_description = t("Tools.separate_by_loose_parts.desc")
+1 -1
View File
@@ -6,7 +6,7 @@ from typing import List, Tuple
from ..core.common import get_selected_armature, is_valid_armature, get_all_meshes, init_progress, update_progress, finish_progress from ..core.common import get_selected_armature, is_valid_armature, get_all_meshes, init_progress, update_progress, finish_progress
@register_wrap @register_wrap
class AutoVisemeButton(bpy.types.Operator): class AvatarToolKit_OT_AutoVisemeButton(bpy.types.Operator):
bl_idname = 'avatar_toolkit.create_visemes' bl_idname = 'avatar_toolkit.create_visemes'
bl_label = t('AutoVisemeButton.label') bl_label = t('AutoVisemeButton.label')
bl_description = t('AutoVisemeButton.desc') bl_description = t('AutoVisemeButton.desc')
+12 -12
View File
@@ -1,13 +1,13 @@
from bpy.types import UIList, Panel, UILayout, Object, Context,Material, Operator from bpy.types import UIList, Panel, UILayout, Object, Context,Material, Operator
import bpy import bpy
from ..core.register import register_wrap from ..core.register import register_wrap
from .panel import AvatarToolkitPanel from .panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
from ..core.common import SceneMatClass, material_list_bool, get_selected_armature from ..core.common import SceneMatClass, MaterialListBool, get_selected_armature
from ..functions.atlas_materials import Atlas_Materials from ..functions.atlas_materials import AvatarToolKit_OT_AtlasMaterials
from ..functions.translations import t from ..functions.translations import t
@register_wrap @register_wrap
class ExpandSection_Materials(Operator): class AvatarToolKit_OT_ExpandSectionMaterials(Operator):
bl_idname = 'avatar_toolkit.expand_section_materials' bl_idname = 'avatar_toolkit.expand_section_materials'
bl_label = "" bl_label = ""
bl_description = "" bl_description = ""
@@ -28,13 +28,13 @@ class ExpandSection_Materials(Operator):
newlist.append(mat_slot.material) newlist.append(mat_slot.material)
newitem: SceneMatClass = context.scene.materials.add() newitem: SceneMatClass = context.scene.materials.add()
newitem.mat = mat_slot.material newitem.mat = mat_slot.material
material_list_bool.old_list[context.scene.name] = newlist MaterialListBool.old_list[context.scene.name] = newlist
else: else:
context.scene.texture_atlas_Has_Mat_List_Shown = False context.scene.texture_atlas_Has_Mat_List_Shown = False
return {'FINISHED'} return {'FINISHED'}
@register_wrap @register_wrap
class MaterialTextureAtlasProperties(UIList): class AvatarToolKit_UL_MaterialTextureAtlasProperties(UIList):
bl_label = t("TextureAtlas.material_list_label") bl_label = t("TextureAtlas.material_list_label")
bl_idname = "Material_UL_avatar_toolkit_texture_atlas_mat_list_mat" bl_idname = "Material_UL_avatar_toolkit_texture_atlas_mat_list_mat"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
@@ -59,13 +59,13 @@ class MaterialTextureAtlasProperties(UIList):
col.prop(item.mat, "texture_atlas_roughness") col.prop(item.mat, "texture_atlas_roughness")
@register_wrap @register_wrap
class TextureAtlasPanel(Panel): class AvatarToolKit_PT_TextureAtlasPanel(Panel):
bl_label = t("TextureAtlas.label") bl_label = t("TextureAtlas.label")
bl_idname = "OBJECT_PT_avatar_toolkit_texture_atlas" bl_idname = "OBJECT_PT_avatar_toolkit_texture_atlas"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Avatar Toolkit" bl_category = CATEGORY_NAME
bl_parent_id = "OBJECT_PT_avatar_toolkit" bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
bl_order = 4 bl_order = 4
def draw(self, context: Context): def draw(self, context: Context):
@@ -77,12 +77,12 @@ class TextureAtlasPanel(Panel):
boxoutter = row.box() boxoutter = row.box()
direction_icon = 'RIGHTARROW' if not context.scene.texture_atlas_Has_Mat_List_Shown else 'DOWNARROW_HLT' direction_icon = 'RIGHTARROW' if not context.scene.texture_atlas_Has_Mat_List_Shown else 'DOWNARROW_HLT'
row = boxoutter.row() row = boxoutter.row()
row.operator(ExpandSection_Materials.bl_idname, text=(t("TextureAtlas.reload_list") if not context.scene.texture_atlas_Has_Mat_List_Shown else t("TextureAtlas.loaded_list")), icon=direction_icon) row.operator(AvatarToolKit_OT_ExpandSectionMaterials.bl_idname, text=(t("TextureAtlas.reload_list") if not context.scene.texture_atlas_Has_Mat_List_Shown else t("TextureAtlas.loaded_list")), icon=direction_icon)
if context.scene.texture_atlas_Has_Mat_List_Shown: if context.scene.texture_atlas_Has_Mat_List_Shown:
row = boxoutter.row() row = boxoutter.row()
row.template_list(MaterialTextureAtlasProperties.bl_idname, 'material_list', context.scene, 'materials', row.template_list(AvatarToolKit_UL_MaterialTextureAtlasProperties.bl_idname, 'material_list', context.scene, 'materials',
context.scene, 'texture_atlas_material_index', rows=12, type='DEFAULT') context.scene, 'texture_atlas_material_index', rows=12, type='DEFAULT')
row = layout.row() row = layout.row()
row.operator(Atlas_Materials.bl_idname, text=t("TextureAtlas.atlas_materials")) row.operator(AvatarToolKit_OT_AtlasMaterials.bl_idname, text=t("TextureAtlas.atlas_materials"))
else: else:
layout.label(text=t("Tools.select_armature"), icon='ERROR') layout.label(text=t("Tools.select_armature"), icon='ERROR')
+12 -10
View File
@@ -1,18 +1,20 @@
import bpy import bpy
from ..core.register import register_wrap from ..core.register import register_wrap
from .panel import AvatarToolkitPanel from .panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
from ..functions.translations import t from ..functions.translations import t
from ..functions.remove_doubles_safely import RemoveDoublesSafely, RemoveDoublesSafelyAdvanced from ..functions.remove_doubles_safely import AvatarToolKit_OT_RemoveDoublesSafely, AvatarToolKit_OT_RemoveDoublesSafelyAdvanced
from ..core.common import get_selected_armature from ..core.common import get_selected_armature
from ..functions.join_meshes import AvatarToolKit_OT_JoinAllMeshes, AvatarToolKit_OT_JoinSelectedMeshes
from ..functions.combine_materials import AvatarToolKit_OT_CombineMaterials
@register_wrap @register_wrap
class AvatarToolkitOptimizationPanel(bpy.types.Panel): class AvatarToolkit_PT_OptimizationPanel(bpy.types.Panel):
bl_label = t("Optimization.label") bl_label = t("Optimization.label")
bl_idname = "OBJECT_PT_avatar_toolkit_optimization" bl_idname = "OBJECT_PT_avatar_toolkit_optimization"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Avatar Toolkit" bl_category = CATEGORY_NAME
bl_parent_id = "OBJECT_PT_avatar_toolkit" bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
bl_order = 2 bl_order = 2
def draw(self, context): def draw(self, context):
@@ -24,18 +26,18 @@ class AvatarToolkitOptimizationPanel(bpy.types.Panel):
row = layout.row() row = layout.row()
row.scale_y = 1.2 row.scale_y = 1.2
row.operator("avatar_toolkit.combine_materials", text=t("Optimization.combine_materials.label"), icon='MATERIAL') row.operator(AvatarToolKit_OT_CombineMaterials.bl_idname, text=t("Optimization.combine_materials.label"), icon='MATERIAL')
row = layout.row(align=True) row = layout.row(align=True)
row.scale_y = 1.2 row.scale_y = 1.2
row.operator(RemoveDoublesSafely.bl_idname, text=t("Optimization.remove_doubles_safely.label"), icon='SNAP_VERTEX') row.operator(AvatarToolKit_OT_RemoveDoublesSafely.bl_idname, text=t("Optimization.remove_doubles_safely.label"), icon='SNAP_VERTEX')
row.operator(RemoveDoublesSafelyAdvanced.bl_idname, text=t("Optimization.remove_doubles_safely_advanced.label"), icon = "ACTION") row.operator(AvatarToolKit_OT_RemoveDoublesSafelyAdvanced.bl_idname, text=t("Optimization.remove_doubles_safely_advanced.label"), icon = "ACTION")
layout.separator(factor=0.5) layout.separator(factor=0.5)
layout.label(text=t("Optimization.joinmeshes.label"), icon='SETTINGS') layout.label(text=t("Optimization.joinmeshes.label"), icon='SETTINGS')
row = layout.row(align=True) row = layout.row(align=True)
row.scale_y = 1.2 row.scale_y = 1.2
row.operator("avatar_toolkit.join_all_meshes", text=t("Optimization.join_all_meshes.label"), icon='OUTLINER_OB_MESH') row.operator(AvatarToolKit_OT_JoinAllMeshes.bl_idname, text=t("Optimization.join_all_meshes.label"), icon='OUTLINER_OB_MESH')
row.operator("avatar_toolkit.join_selected_meshes", text=t("Optimization.join_selected_meshes.label"), icon='STICKY_UVS_LOC') row.operator(AvatarToolKit_OT_JoinSelectedMeshes.bl_idname, text=t("Optimization.join_selected_meshes.label"), icon='STICKY_UVS_LOC')
else: else:
layout.label(text=t("Optimization.select_armature"), icon='ERROR') layout.label(text=t("Optimization.select_armature"), icon='ERROR')
+4 -2
View File
@@ -2,13 +2,15 @@ import bpy
from ..core.register import register_wrap from ..core.register import register_wrap
from ..functions.translations import t from ..functions.translations import t
CATEGORY_NAME = "Avatar Toolkit"
@register_wrap @register_wrap
class AvatarToolkitPanel(bpy.types.Panel): class AvatarToolKit_PT_AvatarToolkitPanel(bpy.types.Panel):
bl_label = t("AvatarToolkit.label") bl_label = t("AvatarToolkit.label")
bl_idname = "OBJECT_PT_avatar_toolkit" bl_idname = "OBJECT_PT_avatar_toolkit"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Avatar Toolkit" bl_category = CATEGORY_NAME
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
+42 -62
View File
@@ -1,23 +1,23 @@
import bpy import bpy
from ..core.register import register_wrap from ..core.register import register_wrap
from .panel import AvatarToolkitPanel from .panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
from ..core.export_resonite import AvatarToolKit_OT_ExportResonite
from bpy.types import Context, Mesh, Panel, Operator from bpy.types import Context, Mesh, Panel, Operator
from ..functions.translations import t from ..functions.translations import t
from ..core.import_pmx import import_pmx from ..core.import_pmx import import_pmx
from ..core.import_pmd import import_pmd from ..core.import_pmd import import_pmd
from ..functions.import_anything import ImportAnyModel from ..functions.import_anything import AvatarToolKit_OT_ImportAnyModel
from ..core.common import get_selected_armature, set_selected_armature, get_all_meshes from ..core.common import get_selected_armature, set_selected_armature, get_all_meshes
@register_wrap
@register_wrap @register_wrap
class AvatarToolkitQuickAccessPanel(Panel): class AvatarToolkitQuickAccessPanel(Panel):
bl_label = t("Quick_Access.label") bl_label = t("Quick_Access.label")
bl_idname = "OBJECT_PT_avatar_toolkit_quick_access" bl_idname = "OBJECT_PT_avatar_toolkit_quick_access"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Avatar Toolkit" bl_category = CATEGORY_NAME
bl_parent_id = "OBJECT_PT_avatar_toolkit" bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
bl_order = 1 bl_order = 1
def draw(self, context: Context): def draw(self, context: Context):
@@ -35,8 +35,8 @@ class AvatarToolkitQuickAccessPanel(Panel):
row = layout.row(align=True) row = layout.row(align=True)
row.scale_y = 1.5 row.scale_y = 1.5
row.operator(ImportAnyModel.bl_idname, text=t("Quick_Access.import"), icon='IMPORT') row.operator(AvatarToolKit_OT_ImportAnyModel.bl_idname, text=t("Quick_Access.import"), icon='IMPORT')
row.operator(AVATAR_TOOLKIT_OT_export_menu.bl_idname, text=t("Quick_Access.export"), icon='EXPORT') row.operator(AVATAR_TOOLKIT_OT_ExportMenu.bl_idname, text=t("Quick_Access.export"), icon='EXPORT')
if get_selected_armature(context) != None: if get_selected_armature(context) != None:
if(context.mode == "POSE"): if(context.mode == "POSE"):
@@ -50,6 +50,40 @@ class AvatarToolkitQuickAccessPanel(Panel):
row = layout.row(align=True) row = layout.row(align=True)
row.operator(AvatarToolkit_OT_StartPoseMode.bl_idname, text=t("Quick_Access.start_pose_mode.label"), icon='POSE_HLT') row.operator(AvatarToolkit_OT_StartPoseMode.bl_idname, text=t("Quick_Access.start_pose_mode.label"), icon='POSE_HLT')
@register_wrap
class AVATAR_TOOLKIT_OT_ExportMenu(bpy.types.Operator):
bl_idname = "avatar_toolkit.export_menu"
bl_label = t("Quick_Access.export_menu.label")
bl_description = t("Quick_Access.export_menu.desc")
@classmethod
def poll(cls, context):
return any(obj.type == 'MESH' for obj in context.scene.objects)
def execute(self, context: Context) -> set[str]:
return {'FINISHED'}
def invoke(self, context: Context, event):
wm = context.window_manager
return wm.invoke_popup(self, width=200)
def draw(self, context: Context):
layout = self.layout
layout.label(text=t("Quick_Access.select_export.label"), icon='EXPORT')
layout.operator(AvatarToolKit_OT_ExportResonite.bl_idname, text=t("Quick_Access.select_export_resonite.label"), icon='SCENE_DATA')
layout.operator(AVATAR_TOOLKIT_OT_ExportFbx.bl_idname, text=t("Quick_Access.export_fbx.label"), icon='OBJECT_DATA')
@register_wrap
class AVATAR_TOOLKIT_OT_ExportFbx(bpy.types.Operator):
bl_idname = 'avatar_toolkit.export_fbx'
bl_label = t("Quick_Access.export_fbx.label")
bl_description = t("Quick_Access.export_fbx.desc")
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
def execute(self, context) -> set[str]:
bpy.ops.export_scene.fbx('INVOKE_DEFAULT')
return {'FINISHED'}
@register_wrap @register_wrap
class AvatarToolkit_OT_StartPoseMode(Operator): class AvatarToolkit_OT_StartPoseMode(Operator):
bl_idname = 'avatar_toolkit.start_pose_mode' bl_idname = 'avatar_toolkit.start_pose_mode'
@@ -62,18 +96,12 @@ class AvatarToolkit_OT_StartPoseMode(Operator):
return get_selected_armature(context) != None and context.mode != "POSE" return get_selected_armature(context) != None and context.mode != "POSE"
def execute(self, context: Context) -> set[str]: def execute(self, context: Context) -> set[str]:
#give an active object so the next line doesn't throw an error.
context.view_layer.objects.active = get_selected_armature(context) context.view_layer.objects.active = get_selected_armature(context)
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
#deselect everything and select just our armature, then go into pose on just our selected armature. - @989onan
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
context.view_layer.objects.active = get_selected_armature(context) context.view_layer.objects.active = get_selected_armature(context)
context.view_layer.objects.active.select_set(True) context.view_layer.objects.active.select_set(True)
bpy.ops.object.mode_set(mode='POSE') bpy.ops.object.mode_set(mode='POSE')
return {'FINISHED'} return {'FINISHED'}
@register_wrap @register_wrap
@@ -88,14 +116,11 @@ class AvatarToolkit_OT_StopPoseMode(Operator):
return get_selected_armature(context) != None and context.mode == "POSE" return get_selected_armature(context) != None and context.mode == "POSE"
def execute(self, context: Context) -> set[str]: def execute(self, context: Context) -> set[str]:
#this is done so that transforms are cleared but user selection is respected. - @989onan
bpy.ops.pose.transforms_clear() bpy.ops.pose.transforms_clear()
bpy.ops.pose.select_all(action="INVERT") bpy.ops.pose.select_all(action="INVERT")
bpy.ops.pose.transforms_clear() bpy.ops.pose.transforms_clear()
bpy.ops.pose.select_all(action="INVERT") bpy.ops.pose.select_all(action="INVERT")
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
return {'FINISHED'} return {'FINISHED'}
@register_wrap @register_wrap
@@ -112,10 +137,8 @@ class AvatarToolkit_OT_ApplyPoseAsShapekey(Operator):
def execute(self, context: Context): def execute(self, context: Context):
bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="OBJECT")
for obj in get_all_meshes(context): for obj in get_all_meshes(context):
modifier_armature_name: str = "" modifier_armature_name: str = ""
context.view_layer.objects.active = obj context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.select_all(action="DESELECT") bpy.ops.object.select_all(action="DESELECT")
context.view_layer.objects.active = obj context.view_layer.objects.active = obj
@@ -125,7 +148,6 @@ class AvatarToolkit_OT_ApplyPoseAsShapekey(Operator):
arm_modifier: bpy.types.ArmatureModifier = modifier arm_modifier: bpy.types.ArmatureModifier = modifier
modifier_armature_name = arm_modifier.object.name modifier_armature_name = arm_modifier.object.name
bpy.ops.object.modifier_apply_as_shapekey(modifier=modifier_armature_name,keep_modifier=True,report=True) bpy.ops.object.modifier_apply_as_shapekey(modifier=modifier_armature_name,keep_modifier=True,report=True)
return {'FINISHED'} return {'FINISHED'}
@register_wrap @register_wrap
@@ -143,8 +165,6 @@ class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
for obj in get_all_meshes(context): for obj in get_all_meshes(context):
mesh_data: Mesh = obj.data mesh_data: Mesh = obj.data
if mesh_data.shape_keys: if mesh_data.shape_keys:
shape_key_obj_list: list[bpy.types.Object] = [] shape_key_obj_list: list[bpy.types.Object] = []
modifier_armature_name: str = "" modifier_armature_name: str = ""
@@ -163,12 +183,10 @@ class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
context.view_layer.objects.active = obj context.view_layer.objects.active = obj
obj.select_set(True) obj.select_set(True)
#create duplicate of object
bpy.ops.object.duplicate() bpy.ops.object.duplicate()
shape_obj = context.view_layer.objects.active shape_obj = context.view_layer.objects.active
#make current shapekey a separate object
shape_obj.active_shape_key_index = idx shape_obj.active_shape_key_index = idx
shape_obj.name = shape.name shape_obj.name = shape.name
@@ -181,10 +199,7 @@ class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
bpy.ops.object.modifier_apply(modifier=modifier_armature_name) bpy.ops.object.modifier_apply(modifier=modifier_armature_name)
#for modifier_name in [i.name for i in shape_obj.modifiers]: shape_key_obj_list.append(shape_obj)
# bpy.ops.object.modifier_remove(modifier=modifier_name)
shape_key_obj_list.append(shape_obj) #add to a list of shape key objects
context.view_layer.objects.active = obj context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="OBJECT")
@@ -202,7 +217,6 @@ class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
bpy.ops.object.join_shapes() bpy.ops.object.join_shapes()
except: except:
self.report({'ERROR'}, t("Quick_Access.apply_armature_failed")) self.report({'ERROR'}, t("Quick_Access.apply_armature_failed"))
#delete shapekey objects to not leave ourselves in a bad exit state - @989onan
context.view_layer.objects.active = shape_key_obj_list[0] context.view_layer.objects.active = shape_key_obj_list[0]
obj.select_set(False) obj.select_set(False)
bpy.ops.object.delete(confirm=False) bpy.ops.object.delete(confirm=False)
@@ -233,37 +247,3 @@ class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
bpy.ops.pose.armature_apply(selected=False) bpy.ops.pose.armature_apply(selected=False)
return {'FINISHED'} return {'FINISHED'}
@register_wrap
class AVATAR_TOOLKIT_OT_export_menu(Operator):
bl_idname = "avatar_toolkit.export_menu"
bl_label = t("Quick_Access.export_menu.label")
bl_description = t("Quick_Access.export_menu.desc")
@classmethod
def poll(cls, context):
return any(obj.type == 'MESH' for obj in context.scene.objects)
def execute(self, context: Context) -> set[str]:
return {'FINISHED'}
def invoke(self, context: Context, event):
wm = context.window_manager
return wm.invoke_popup(self, width=200)
def draw(self, context: Context):
layout = self.layout
layout.label(text=t("Quick_Access.select_export.label"), icon='EXPORT')
layout.operator("avatar_toolkit.export_resonite", text=t("Quick_Access.select_export_resonite.label"), icon='SCENE_DATA')
layout.operator("avatar_toolkit.export_fbx", text=t("Quick_Access.export_fbx.label"), icon='OBJECT_DATA')
@register_wrap
class AVATAR_TOOLKIT_OT_export_fbx(Operator):
bl_idname = 'avatar_toolkit.export_fbx'
bl_label = t("Quick_Access.export_fbx.label")
bl_description = t("Quick_Access.export_fbx.desc")
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
def execute(self, context) -> set[str]:
bpy.ops.export_scene.fbx('INVOKE_DEFAULT')
return {'FINISHED'}
+3 -3
View File
@@ -1,6 +1,6 @@
import bpy import bpy
from ..core.register import register_wrap from ..core.register import register_wrap
from .panel import AvatarToolkitPanel from .panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
from ..functions.translations import t from ..functions.translations import t
@register_wrap @register_wrap
@@ -9,8 +9,8 @@ class AvatarToolkitSettingsPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_avatar_toolkit_settings" bl_idname = "OBJECT_PT_avatar_toolkit_settings"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Avatar Toolkit" bl_category = CATEGORY_NAME
bl_parent_id = "OBJECT_PT_avatar_toolkit" bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
bl_order = 6 bl_order = 6
def draw(self, context): def draw(self, context):
+13 -12
View File
@@ -1,21 +1,22 @@
import bpy import bpy
from ..core.register import register_wrap from ..core.register import register_wrap
from .panel import AvatarToolkitPanel from .panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
from bpy.types import Context from bpy.types import Context
from ..functions.digitigrade_legs import CreateDigitigradeLegs from ..functions.digitigrade_legs import AvatarToolKit_OT_CreateDigitigradeLegs
from ..functions.resonite_functions import AvatarToolKit_OT_ConvertToResonite
from ..functions.translations import t from ..functions.translations import t
from ..core.common import get_selected_armature from ..core.common import get_selected_armature
from ..functions.seperate_by import SeparateByMaterials, SeparateByLooseParts from ..functions.seperate_by import AvatarToolKit_OT_SeparateByMaterials, AvatarToolKit_OT_SeparateByLooseParts
from ..functions.additional_tools import ApplyTransforms from ..functions.additional_tools import AvatarToolKit_OT_ApplyTransforms
@register_wrap @register_wrap
class AvatarToolkitToolsPanel(bpy.types.Panel): class AvatarToolkit_PT_ToolsPanel(bpy.types.Panel):
bl_label = t("Tools.label") bl_label = t("Tools.label")
bl_idname = "OBJECT_PT_avatar_toolkit_tools" bl_idname = "OBJECT_PT_avatar_toolkit_tools"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Avatar Toolkit" bl_category = CATEGORY_NAME
bl_parent_id = "OBJECT_PT_avatar_toolkit" bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
bl_order = 3 bl_order = 3
def draw(self, context: Context): def draw(self, context: Context):
@@ -28,15 +29,15 @@ class AvatarToolkitToolsPanel(bpy.types.Panel):
row = layout.row(align=True) row = layout.row(align=True)
row.scale_y = 1.5 row.scale_y = 1.5
row.operator("avatar_toolkit.convert_to_resonite", text=t("Tools.convert_to_resonite.label"), icon='SCENE_DATA') row.operator(AvatarToolKit_OT_ConvertToResonite.bl_idname, text=t("Tools.convert_to_resonite.label"), icon='SCENE_DATA')
row = layout.row(align=True) row = layout.row(align=True)
row.operator(CreateDigitigradeLegs.bl_idname, text=t("Tools.create_digitigrade_legs.label"), icon='BONE_DATA') row.operator(AvatarToolKit_OT_CreateDigitigradeLegs.bl_idname, text=t("Tools.create_digitigrade_legs.label"), icon='BONE_DATA')
layout.separator() layout.separator()
row = layout.row(align=True) row = layout.row(align=True)
layout.label(text=t("Tools.separate_by.label"), icon='MESH_DATA') layout.label(text=t("Tools.separate_by.label"), icon='MESH_DATA')
row.operator(SeparateByMaterials.bl_idname, text=t("Tools.separate_by_materials.label"), icon='MATERIAL') row.operator(AvatarToolKit_OT_SeparateByMaterials.bl_idname, text=t("Tools.separate_by_materials.label"), icon='MATERIAL')
row.operator(SeparateByLooseParts.bl_idname, text=t("Tools.separate_by_loose_parts.label"), icon='OUTLINER_OB_MESH') row.operator(AvatarToolKit_OT_SeparateByLooseParts.bl_idname, text=t("Tools.separate_by_loose_parts.label"), icon='OUTLINER_OB_MESH')
row = layout.row(align=True) row = layout.row(align=True)
row.operator(ApplyTransforms.bl_idname, text=t("Tools.apply_transforms.label"), icon='OBJECT_ORIGIN') row.operator(AvatarToolKit_OT_ApplyTransforms.bl_idname, text=t("Tools.apply_transforms.label"), icon='OBJECT_ORIGIN')
else: else:
layout.label(text=t("Tools.select_armature"), icon='ERROR') layout.label(text=t("Tools.select_armature"), icon='ERROR')
+5 -3
View File
@@ -1,5 +1,7 @@
import bpy import bpy
from ..core.register import register_wrap from ..core.register import register_wrap
from .panel import AvatarToolKit_PT_AvatarToolkitPanel, CATEGORY_NAME
from ..functions.viseme import AvatarToolKit_OT_AutoVisemeButton
from ..functions.translations import t from ..functions.translations import t
from ..core.common import get_selected_armature from ..core.common import get_selected_armature
@@ -9,8 +11,8 @@ class AvatarToolkitVisemePanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_avatar_toolkit_viseme" bl_idname = "OBJECT_PT_avatar_toolkit_viseme"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
bl_category = "Avatar Toolkit" bl_category = CATEGORY_NAME
bl_parent_id = "OBJECT_PT_avatar_toolkit" bl_parent_id = AvatarToolKit_PT_AvatarToolkitPanel.bl_idname
bl_order = 5 bl_order = 5
def draw(self, context: bpy.types.Context) -> None: def draw(self, context: bpy.types.Context) -> None:
@@ -32,7 +34,7 @@ class AvatarToolkitVisemePanel(bpy.types.Panel):
row = layout.row() row = layout.row()
row.scale_y = 1.2 row.scale_y = 1.2
row.operator("avatar_toolkit.create_visemes", text=t('VisemePanel.create_visemes'), icon='TRIA_RIGHT') row.operator(AvatarToolKit_OT_AutoVisemeButton.bl_idname, text=t('VisemePanel.create_visemes'), icon='TRIA_RIGHT')
else: else:
layout.label(text=t('VisemePanel.error.noShapekeys'), icon='ERROR') layout.label(text=t('VisemePanel.error.noShapekeys'), icon='ERROR')
else: else: