Plugin Registration Changes

- Re-wrote how the plugin registers itself.
- No longer need @register_wrapper classes get auto detected and added.
- The new Auto loader is much better then the old way, no longer need "if "bpy" not in locals():" this was an old way of doing things and wasn't really efficient.

 using auto_load.py provides several advantages:

- It automatically discovers and loads all modules in the addon.
- It handles dependencies between classes correctly through topological sorting.
- It manages registration order automatically.
- It properly handles unregistration in the correct order.

This approach is much less error prone and I not had any issues so far. However it still needs testing fully.

I have also start to re-organise files into folders as well, this is going to be needed so we don't have a long list of files as Avatar Toolkit is getting larger then i originally planned.
This commit is contained in:
Yusarina
2024-12-02 01:52:11 +00:00
parent ac6e98c27e
commit fe8f5f69d5
40 changed files with 581 additions and 580 deletions
-18
View File
@@ -1,18 +0,0 @@
from ..core.register import register_wrap
#to reload all things in this directory and import them properly - @989onan
if "bpy" not in locals():
import bpy
import glob
import os
from os.path import dirname, basename, isfile, join
modules = glob.glob(join(dirname(__file__), "*.py"))
for module_name in [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]:
exec("from . import "+module_name)
print("importing " +module_name)
else:
import importlib
modules = glob.glob(join(dirname(__file__), "*.py"))
for module_name in [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]:
exec("importlib.reload("+module_name+")")
print("reloading " +module_name)
+6 -7
View File
@@ -1,11 +1,10 @@
import bpy
import math
from bpy.types import Context, Operator
from ..core.register import register_wrap
from ..core.common import get_selected_armature, is_valid_armature, get_all_meshes
from ..functions.translations import t
from ..core.translations import t
@register_wrap
class AvatarToolKit_OT_ApplyTransforms(Operator):
bl_idname = "avatar_toolkit.apply_transforms"
bl_label = t("Tools.apply_transforms.label")
@@ -37,7 +36,7 @@ class AvatarToolKit_OT_ApplyTransforms(Operator):
self.report({'INFO'}, t("Tools.apply_transforms.success"))
return {'FINISHED'}
@register_wrap
class AvatarToolKit_OT_ConnectBones(Operator):
bl_idname = "avatar_toolkit.connect_bones"
bl_label = t("Tools.connect_bones.label")
@@ -90,7 +89,7 @@ class AvatarToolKit_OT_ConnectBones(Operator):
layout = self.layout
layout.prop(self, "min_distance")
@register_wrap
class AvatarToolKit_OT_DeleteBoneConstraints(Operator):
bl_idname = "avatar_toolkit.delete_bone_constraints"
bl_label = t("Tools.delete_bone_constraints.label")
@@ -120,7 +119,7 @@ class AvatarToolKit_OT_DeleteBoneConstraints(Operator):
self.report({'INFO'}, t("Tools.delete_bone_constraints.success").format(constraints_removed=constraints_removed))
return {'FINISHED'}
@register_wrap
class AvatarToolKit_OT_SeparateByMaterials(Operator):
bl_idname = "avatar_toolkit.separate_by_materials"
bl_label = t("Tools.separate_by_materials.label")
@@ -140,7 +139,7 @@ class AvatarToolKit_OT_SeparateByMaterials(Operator):
self.report({'INFO'}, t("Tools.separate_by_materials.success"))
return {'FINISHED'}
@register_wrap
class AvatarToolKit_OT_SeparateByLooseParts(Operator):
bl_idname = "avatar_toolkit.separate_by_loose_parts"
bl_label = t("Tools.separate_by_loose_parts.label")
+9 -10
View File
@@ -1,13 +1,12 @@
import bpy
from ..core.register import register_wrap
from bpy.types import Context, Mesh, Panel, Operator, Armature, EditBone
from ..functions.translations import t
from ..core.translations import t
from ..core.common import get_selected_armature, get_all_meshes
from ..core import common
from ..core.dictionaries import bone_names
from mathutils import Matrix
@register_wrap
class AvatarToolkit_OT_StartPoseMode(Operator):
bl_idname = 'avatar_toolkit.start_pose_mode'
bl_label = t("Quick_Access.start_pose_mode.label")
@@ -33,7 +32,7 @@ class AvatarToolkit_OT_StartPoseMode(Operator):
return {'FINISHED'}
@register_wrap
class AvatarToolkit_OT_StopPoseMode(Operator):
bl_idname = 'avatar_toolkit.stop_pose_mode'
bl_label = t("Quick_Access.stop_pose_mode.label")
@@ -55,7 +54,7 @@ class AvatarToolkit_OT_StopPoseMode(Operator):
return {'FINISHED'}
@register_wrap
class AvatarToolkit_OT_ApplyPoseAsShapekey(Operator):
bl_idname = 'avatar_toolkit.apply_pose_as_shapekey'
bl_label = t("Quick_Access.apply_pose_as_shapekey.label")
@@ -98,7 +97,7 @@ class AvatarToolkit_OT_ApplyPoseAsShapekey(Operator):
self.report({'INFO'}, t('Tools.apply_pose_as_rest.success'))
return {'FINISHED'}
@register_wrap
class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
bl_idname = 'avatar_toolkit.apply_pose_as_rest'
bl_label = t("Quick_Access.apply_pose_as_rest.label")
@@ -117,7 +116,7 @@ class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
return {'CANCELLED'}
return {'FINISHED'}
@register_wrap
class AvatarToolkit_OT_RemoveZeroWeightBones(Operator):
bl_idname = "avatar_toolkit.remove_zero_weight_bones"
bl_label = t("Tools.remove_zero_weight_bones.label")
@@ -218,7 +217,7 @@ class AvatarToolkit_OT_RemoveZeroWeightBones(Operator):
return {'FINISHED'}
@register_wrap
class AvatarToolkit_OT_MergeBonesToActive(Operator):
bl_idname = "avatar_toolkit.merge_bones_to_active"
bl_label = t("Tools.merge_bones_to_active.label")
@@ -267,7 +266,7 @@ class AvatarToolkit_OT_MergeBonesToActive(Operator):
bpy.ops.object.mode_set(mode=prev_mode)
return {'FINISHED'}
@register_wrap
class AvatarToolkit_OT_MergeBonesToParents(Operator):
bl_idname = "avatar_toolkit.merge_bones_to_parents"
bl_label = t("Tools.merge_bones_to_parents.label")
@@ -342,7 +341,7 @@ class AvatarToolkit_OT_MergeBonesToParents(Operator):
bpy.ops.object.mode_set(mode=prev_mode)
return {'FINISHED'}
@register_wrap
class AvatarToolkit_OT_MergeArmatures(Operator):
bl_idname = "avatar_toolkit.merge_armatures"
bl_label = t("MergeArmature.merge_armatures.label")
+2 -3
View File
@@ -5,10 +5,9 @@ import bpy
import os
from typing import List, Tuple, Optional
from bpy.types import Material, Operator, Context, Object, Image, Mesh, MeshUVLoopLayer, Float2AttributeValue, ShaderNodeTexImage, ShaderNodeBsdfPrincipled, ShaderNodeNormalMap
from ..core.register import register_wrap
from ..core.common import SceneMatClass, MaterialListBool
from ..core.packer.rectangle_packer import MaterialImageList, BinPacker
from ..functions.translations import t
from ..core.translations import t
class MaterialImageList:
def __init__(self):
@@ -134,7 +133,7 @@ def prep_images_in_scene(context: Context) -> list[MaterialImageList]:
@register_wrap
class AvatarToolKit_OT_AtlasMaterials(Operator):
bl_idname = "avatar_toolkit.atlas_materials"
+2 -3
View File
@@ -3,8 +3,7 @@ import re
from typing import List, Tuple, Optional, Set, Dict
from bpy.types import Material, Operator, Context, Object, NodeTree
from ..core.common import clean_material_names, get_selected_armature, is_valid_armature, get_all_meshes, init_progress, update_progress, finish_progress
from ..core.register import register_wrap
from ..functions.translations import t
from ..core.translations import t
def textures_match(tex1: bpy.types.ImageTexture, tex2: bpy.types.ImageTexture) -> bool:
return tex1.image == tex2.image and tex1.extension == tex2.extension
@@ -52,7 +51,7 @@ def get_base_name(name: str) -> str:
mat_match = re.match(r"^(.*)\.\d{3}$", name)
return mat_match.group(1) if mat_match else name
@register_wrap
class AvatarToolKit_OT_CombineMaterials(Operator):
bl_idname = "avatar_toolkit.combine_materials"
bl_label = t("Optimization.combine_materials.label")
+2 -3
View File
@@ -1,11 +1,10 @@
import bpy
from ..core import common
from ..core import register_wrap
from .translations import t
from ..core.translations import t
import re
@register_wrap
class AvatarToolKit_OT_CreateDigitigradeLegs(bpy.types.Operator):
bl_idname = "avatar_toolkit.create_digitigrade_legs"
bl_label = t('Tools.create_digitigrade_legs.label')
+5 -6
View File
@@ -1,16 +1,15 @@
import bpy
from bpy.types import Operator
from bpy_extras.io_utils import ImportHelper
from ..core.register import register_wrap
from ..core.importer import imports, import_types
from ..core.importers.importer import imports, import_types
from ..core.common import remove_default_objects
from ..functions.translations import t
from ..core.translations import t
import pathlib
import os
VRM_IMPORTER_URL = "https://github.com/saturday06/VRM_Addon_for_Blender"
@register_wrap
class AvatarToolKit_OT_ImportAnyModel(Operator, ImportHelper):
bl_idname = 'avatar_toolkit.import_any_model'
bl_label = t('Tools.import_any_model.label')
@@ -67,7 +66,7 @@ class AvatarToolKit_OT_ImportAnyModel(Operator, ImportHelper):
self.report({'INFO'}, t('Quick_Access.import_success'))
return {'FINISHED'}
@register_wrap
class VRMImporterPopup(Operator):
bl_idname = "wm.vrm_importer_popup"
bl_label = "VRM Importer Not Installed"
@@ -87,7 +86,7 @@ class VRMImporterPopup(Operator):
#TODO: This needs to be done with our own MMD importer.
"""
#stolen from cats. Oh wait I made this code riiiiiiight - @989onan
@register_wrap
class ImportMMDAnimation(bpy.types.Operator, ImportHelper):
bl_idname = 'avatar_toolkit.import_mmd_animation'
bl_label = t('Importer.mmd_anim_importer.label')
+5 -6
View File
@@ -3,10 +3,9 @@ import bpy
from typing import List, Optional, Set
from bpy.types import Operator, Context, Object
from ..core.common import fix_uv_coordinates, get_selected_armature, get_all_meshes, is_valid_armature, apply_shapekey_to_basis, has_shapekeys, select_current_armature, init_progress, update_progress, finish_progress
from ..functions.translations import t
from ..core.register import register_wrap
from ..core.translations import t
@register_wrap
class AvatarToolkit_OT_RemoveUnusedShapekeys(bpy.types.Operator):
tolerance: bpy.props.FloatProperty(name=t("Tools.remove_unused_shapekeys.tolerance.label"), default=0.001, description=t("Tools.remove_unused_shapekeys.tolerance.desc"))
bl_idname = "avatar_toolkit.remove_unused_shapekeys"
@@ -56,7 +55,7 @@ class AvatarToolkit_OT_RemoveUnusedShapekeys(bpy.types.Operator):
continue
ob.shape_key_remove(ob.data.shape_keys.key_blocks[kb_name])
@register_wrap
class AvatarToolkit_OT_ApplyShapeKey(bpy.types.Operator):
bl_idname = "avatar_toolkit.apply_shape_key"
bl_label = t("Tools.apply_shape_key.label")
@@ -79,7 +78,7 @@ class AvatarToolkit_OT_ApplyShapeKey(bpy.types.Operator):
self.report({'ERROR'}, t("Tools.apply_shape_key.error"))
return {'FINISHED'}
@register_wrap
class AvatarToolKit_OT_JoinAllMeshes(Operator):
bl_idname = "avatar_toolkit.join_all_meshes"
bl_label = t("Optimization.join_all_meshes.label")
@@ -150,7 +149,7 @@ class AvatarToolKit_OT_JoinAllMeshes(Operator):
finish_progress(context)
@register_wrap
class AvatarToolKit_OT_JoinSelectedMeshes(Operator):
bl_idname = "avatar_toolkit.join_selected_meshes"
bl_label = t("Optimization.join_selected_meshes.label")
+5 -6
View File
@@ -2,13 +2,12 @@ import bpy
import numpy as np
import re
from bpy.types import Operator, Context, Material, ShaderNodeTexImage, ShaderNodeGroup, Object
from ..core.register import register_wrap
from ..functions.translations import t
from ..core.translations import t
from ..core.common import get_selected_armature, is_valid_armature, get_all_meshes, init_progress, update_progress, finish_progress
from ..functions.additional_tools import AvatarToolKit_OT_ConnectBones, AvatarToolKit_OT_DeleteBoneConstraints
from ..functions.armature_modifying import AvatarToolkit_OT_RemoveZeroWeightBones, AvatarToolkit_OT_MergeBonesToParents
@register_wrap
class AvatarToolKit_OT_CleanupMesh(Operator):
bl_idname = "avatar_toolkit.cleanup_mesh"
bl_label = t("MMDOptions.cleanup_mesh.label")
@@ -61,7 +60,7 @@ class AvatarToolKit_OT_CleanupMesh(Operator):
if key.name != 'Basis' and all(abs(key.data[i].co[j] - obj.data.shape_keys.reference_key.data[i].co[j]) < 0.0001 for i in range(len(key.data)) for j in range(3)):
obj.shape_key_remove(key)
@register_wrap
class AvatarToolKit_OT_OptimizeWeights(Operator):
bl_idname = "avatar_toolkit.optimize_weights"
bl_label = t("MMDOptions.optimize_weights.label")
@@ -108,7 +107,7 @@ class AvatarToolKit_OT_OptimizeWeights(Operator):
for g in sorted_groups[self.max_weights:]:
obj.vertex_groups[g.group].remove([v.index])
@register_wrap
class AvatarToolKit_OT_OptimizeArmature(Operator):
bl_idname = "avatar_toolkit.optimize_armature"
bl_label = t("MMDOptions.optimize_armature.label")
@@ -339,7 +338,7 @@ def fix_vrm_shader(material: Material):
material.node_tree.links = [link for link in material.node_tree.links
if not (link.from_node == node or link.to_node == node)]
@register_wrap
class AvatarToolKit_OT_ConvertMaterials(Operator):
bl_idname = "avatar_toolkit.convert_materials"
bl_label = t("MMDOptions.convert_materials.label")
+3 -4
View File
@@ -1,9 +1,8 @@
import bpy
from typing import List, TypedDict, Any
from bpy.types import Operator, Context, Object
from ..core.register import register_wrap
from ..core.common import get_selected_armature, is_valid_armature, select_current_armature, get_all_meshes
from ..functions.translations import t
from ..core.translations import t
class meshEntry(TypedDict):
mesh: Object
@@ -11,7 +10,7 @@ class meshEntry(TypedDict):
vertices: int
cur_vertex_pass: int
@register_wrap
class AvatarToolKit_OT_RemoveDoublesSafelyAdvanced(Operator):
bl_idname = "avatar_toolkit.remove_doubles_safely_advanced"
bl_label = t("Optimization.remove_doubles_safely_advanced.label")
@@ -39,7 +38,7 @@ class AvatarToolKit_OT_RemoveDoublesSafelyAdvanced(Operator):
return {'RUNNING_MODAL'}
@register_wrap
class AvatarToolKit_OT_RemoveDoublesSafely(Operator):
bl_idname = "avatar_toolkit.remove_doubles_safely"
bl_label = t("Optimization.remove_doubles_safely.label")
+2 -3
View File
@@ -1,13 +1,12 @@
import bpy
from ..core.register import register_wrap
from typing import List, Optional
import re
from bpy.types import Operator, Context, Object
from ..core.dictionaries import bone_names
from ..core.common import get_selected_armature, simplify_bonename, is_valid_armature
from ..functions.translations import t
from ..core.translations import t
@register_wrap
class AvatarToolKit_OT_ConvertToResonite(Operator):
bl_idname = 'avatar_toolkit.convert_to_resonite'
bl_label = t('Tools.convert_to_resonite.label')
+1 -10
View File
@@ -1,18 +1,9 @@
# This code is heavily based on the Rigify-Move-DEF by NyankoNyan (https://github.com/NyankoNyan/Rigify-Move-DEF), which is licensed under the MIT License. We just heavily improve the code and add some new features.
import bpy
from ..core.register import register_wrap
from ..core.common import get_selected_armature, is_valid_armature
from ..functions.translations import t
from ..core.translations import t
from bpy.types import Operator, Context
import bpy
from ..core.register import register_wrap
from ..core.common import get_selected_armature, is_valid_armature
from ..functions.translations import t
from bpy.types import Operator, Context
@register_wrap
class AvatarToolKit_OT_ConvertRigifyToUnity(Operator):
bl_idname = "avatar_toolkit.convert_rigify_to_unity"
bl_label = t("Tools.convert_rigify_to_unity.label")
+2 -3
View File
@@ -4,15 +4,14 @@ from bpy.types import Operator, Object, Context, Mesh, MeshUVLoopLayer
import bmesh
import numpy as np
import math
from ..functions.translations import t
from ..core.register import register_wrap
from ..core.translations import t
class GenerateLoopTreeResult(TypedDict):
tree: dict[str, set[str]]
selected_loops: dict[str,list[int]]
selected_verts: dict[str,int]
@register_wrap
class AvatarToolkit_OT_AlignUVEdgesToTarget(Operator):
bl_idname = "avatar_toolkit.align_uv_edges_to_target"
bl_label = t("avatar_toolkit.align_uv_edges_to_target.label")
+2 -3
View File
@@ -1,11 +1,10 @@
import bpy
from ..core import common
from ..core.register import register_wrap
from ..functions.translations import t
from ..core.translations import t
from typing import List, Tuple
from ..core.common import get_selected_armature, is_valid_armature, get_all_meshes, init_progress, update_progress, finish_progress
@register_wrap
class AvatarToolKit_OT_AutoVisemeButton(bpy.types.Operator):
bl_idname = 'avatar_toolkit.create_visemes'
bl_label = t('AutoVisemeButton.label')