Start of the Major Overhaul
I decided to go through each function and UI section one by one, improving and overhauling things. Each function and section is going to be fully tested and not rushed out. This is the best way to catch things, but also include the code base as much as possible.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import bpy
|
||||
import numpy as np
|
||||
from bpy.types import Operator, Context, Object
|
||||
from typing import List
|
||||
from ..core.translations import t
|
||||
from ..core.common import (
|
||||
get_active_armature,
|
||||
get_all_meshes,
|
||||
apply_pose_as_rest,
|
||||
apply_armature_to_mesh,
|
||||
apply_armature_to_mesh_with_shapekeys,
|
||||
validate_armature
|
||||
)
|
||||
|
||||
class AvatarToolkit_OT_StartPoseMode(Operator):
|
||||
bl_idname = 'avatar_toolkit.start_pose_mode'
|
||||
bl_label = t("Quick_Access.start_pose_mode.label")
|
||||
bl_description = t("Quick_Access.start_pose_mode.desc")
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
armature = get_active_armature(context)
|
||||
if not armature or context.mode == "POSE":
|
||||
return False
|
||||
is_valid, _ = validate_armature(armature)
|
||||
return is_valid
|
||||
|
||||
def execute(self, context: Context) -> set[str]:
|
||||
armature = get_active_armature(context)
|
||||
context.view_layer.objects.active = armature
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
armature.select_set(True)
|
||||
bpy.ops.object.mode_set(mode='POSE')
|
||||
return {'FINISHED'}
|
||||
|
||||
class AvatarToolkit_OT_StopPoseMode(Operator):
|
||||
bl_idname = 'avatar_toolkit.stop_pose_mode'
|
||||
bl_label = t("Quick_Access.stop_pose_mode.label")
|
||||
bl_description = t("Quick_Access.stop_pose_mode.desc")
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return get_active_armature(context) and context.mode == "POSE"
|
||||
|
||||
def execute(self, context: Context) -> set[str]:
|
||||
bpy.ops.pose.transforms_clear()
|
||||
bpy.ops.pose.select_all(action="INVERT")
|
||||
bpy.ops.pose.transforms_clear()
|
||||
bpy.ops.pose.select_all(action="INVERT")
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
return {'FINISHED'}
|
||||
|
||||
class AvatarToolkit_OT_ApplyPoseAsShapekey(Operator):
|
||||
bl_idname = 'avatar_toolkit.apply_pose_as_shapekey'
|
||||
bl_label = t("Quick_Access.apply_pose_as_shapekey.label")
|
||||
bl_description = t("Quick_Access.apply_pose_as_shapekey.desc")
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
armature = get_active_armature(context)
|
||||
if not armature or context.mode != 'POSE':
|
||||
return False
|
||||
is_valid, _ = validate_armature(armature)
|
||||
return is_valid
|
||||
|
||||
def execute(self, context):
|
||||
armature_obj = get_active_armature(context)
|
||||
mesh_objects = get_all_meshes(context)
|
||||
|
||||
for mesh_obj in mesh_objects:
|
||||
if not mesh_obj.data:
|
||||
continue
|
||||
|
||||
if not mesh_obj.data.shape_keys:
|
||||
mesh_obj.shape_key_add(name='Basis')
|
||||
|
||||
new_shape = mesh_obj.shape_key_add(name='Pose_Shapekey', from_mix=False)
|
||||
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
eval_mesh = mesh_obj.evaluated_get(depsgraph)
|
||||
|
||||
for i, v in enumerate(eval_mesh.data.vertices):
|
||||
new_shape.data[i].co = v.co.copy()
|
||||
|
||||
bpy.ops.pose.select_all(action='SELECT')
|
||||
bpy.ops.pose.transforms_clear()
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
self.report({'INFO'}, t('Tools.apply_pose_as_rest.success'))
|
||||
return {'FINISHED'}
|
||||
|
||||
class AvatarToolkit_OT_ApplyPoseAsRest(Operator):
|
||||
bl_idname = 'avatar_toolkit.apply_pose_as_rest'
|
||||
bl_label = t("Quick_Access.apply_pose_as_rest.label")
|
||||
bl_description = t("Quick_Access.apply_pose_as_rest.desc")
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
armature = get_active_armature(context)
|
||||
if not armature or context.mode != "POSE":
|
||||
return False
|
||||
is_valid, _ = validate_armature(armature)
|
||||
return is_valid
|
||||
|
||||
def execute(self, context):
|
||||
if not apply_pose_as_rest(
|
||||
context=context,
|
||||
armature_obj=get_active_armature(context),
|
||||
meshes=get_all_meshes(context)
|
||||
):
|
||||
self.report({'ERROR'}, t("Quick_Access.apply_armature_failed"))
|
||||
return {'CANCELLED'}
|
||||
|
||||
self.report({'INFO'}, t("Tools.apply_pose_as_rest.success"))
|
||||
return {'FINISHED'}
|
||||
Reference in New Issue
Block a user