tweak tools (untested for now)

This commit is contained in:
Nathan
2026-02-19 11:09:48 -07:00
parent 4dee5cbe01
commit a3868e126d
5 changed files with 1096 additions and 21 deletions
+191
View File
@@ -449,6 +449,188 @@ class DLM_OT_picker_replacement_character(Operator):
return {"FINISHED"}
def _tweak_poll(context):
orig, rep = _get_migrator_pair(context)
return orig is not None and rep is not None
class DLM_OT_tweak_add_arm(Operator):
bl_idname = "dlm.tweak_add_arm"
bl_label = "Add Arm Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
from ..ops import tweak_tools
tweak_tools.add_tweak_constraints(orig, rep, "arm")
self.report({"INFO"}, "Arm tweak constraints added.")
return {"FINISHED"}
class DLM_OT_tweak_remove_arm(Operator):
bl_idname = "dlm.tweak_remove_arm"
bl_label = "Remove Arm Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
from ..ops import tweak_tools
n = tweak_tools.remove_tweak_constraints(orig, rep, "arm")
self.report({"INFO"}, f"Removed {n} arm tweak constraints.")
return {"FINISHED"}
class DLM_OT_tweak_bake_arm(Operator):
bl_idname = "dlm.tweak_bake_arm"
bl_label = "Bake Arm Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
props = context.scene.dynamic_link_manager
from ..ops import tweak_tools
ok, msg = tweak_tools.bake_tweak_constraints(
context, orig, rep, "arm",
getattr(props, "tweak_nla_track_name", "") or "",
getattr(props, "tweak_bake_post_clean", False),
)
if ok:
self.report({"INFO"}, msg)
return {"FINISHED"}
self.report({"ERROR"}, msg)
return {"CANCELLED"}
class DLM_OT_tweak_add_leg(Operator):
bl_idname = "dlm.tweak_add_leg"
bl_label = "Add Leg Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
from ..ops import tweak_tools
tweak_tools.add_tweak_constraints(orig, rep, "leg")
self.report({"INFO"}, "Leg tweak constraints added.")
return {"FINISHED"}
class DLM_OT_tweak_remove_leg(Operator):
bl_idname = "dlm.tweak_remove_leg"
bl_label = "Remove Leg Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
from ..ops import tweak_tools
n = tweak_tools.remove_tweak_constraints(orig, rep, "leg")
self.report({"INFO"}, f"Removed {n} leg tweak constraints.")
return {"FINISHED"}
class DLM_OT_tweak_bake_leg(Operator):
bl_idname = "dlm.tweak_bake_leg"
bl_label = "Bake Leg Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
props = context.scene.dynamic_link_manager
from ..ops import tweak_tools
ok, msg = tweak_tools.bake_tweak_constraints(
context, orig, rep, "leg",
getattr(props, "tweak_nla_track_name", "") or "",
getattr(props, "tweak_bake_post_clean", False),
)
if ok:
self.report({"INFO"}, msg)
return {"FINISHED"}
self.report({"ERROR"}, msg)
return {"CANCELLED"}
class DLM_OT_tweak_add_both(Operator):
bl_idname = "dlm.tweak_add_both"
bl_label = "Add Arm & Leg Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
from ..ops import tweak_tools
tweak_tools.add_tweak_constraints(orig, rep, "both")
self.report({"INFO"}, "Arm & leg tweak constraints added.")
return {"FINISHED"}
class DLM_OT_tweak_remove_both(Operator):
bl_idname = "dlm.tweak_remove_both"
bl_label = "Remove Arm & Leg Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
from ..ops import tweak_tools
n = tweak_tools.remove_tweak_constraints(orig, rep, "both")
self.report({"INFO"}, f"Removed {n} tweak constraints.")
return {"FINISHED"}
class DLM_OT_tweak_bake_both(Operator):
bl_idname = "dlm.tweak_bake_both"
bl_label = "Bake Arm & Leg Tweaks"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return _tweak_poll(context)
def execute(self, context):
orig, rep = _get_migrator_pair(context)
props = context.scene.dynamic_link_manager
from ..ops import tweak_tools
ok, msg = tweak_tools.bake_tweak_constraints(
context, orig, rep, "both",
getattr(props, "tweak_nla_track_name", "") or "",
getattr(props, "tweak_bake_post_clean", False),
)
if ok:
self.report({"INFO"}, msg)
return {"FINISHED"}
self.report({"ERROR"}, msg)
return {"CANCELLED"}
OPERATOR_CLASSES = [
DLM_OT_replace_linked_asset,
DLM_OT_scan_linked_assets,
@@ -471,4 +653,13 @@ OPERATOR_CLASSES = [
DLM_OT_migrator_bone_constraints,
DLM_OT_migrator_retarget_relations,
DLM_OT_migrator_basebody_shapekeys,
DLM_OT_tweak_add_arm,
DLM_OT_tweak_remove_arm,
DLM_OT_tweak_bake_arm,
DLM_OT_tweak_add_leg,
DLM_OT_tweak_remove_leg,
DLM_OT_tweak_bake_leg,
DLM_OT_tweak_add_both,
DLM_OT_tweak_remove_both,
DLM_OT_tweak_bake_both,
]
+20
View File
@@ -94,6 +94,26 @@ class DLM_PT_main_panel(Panel):
row.operator("dlm.migrator_retarget_relations", text="Retarget relations", icon="ORIENTATION_PARENT")
row.operator("dlm.migrator_basebody_shapekeys", text="BaseBody ShapeKeys", icon="SHAPEKEY_DATA")
# Tweak Tools
tweak_box = layout.box()
tweak_box.label(text="Tweak Tools", icon="CONSTRAINT")
row = tweak_box.row(align=True)
row.operator("dlm.tweak_add_arm", text="Add Arm", icon="CONSTRAINT_BONE")
row.operator("dlm.tweak_remove_arm", text="Remove Arm", icon="X")
row.operator("dlm.tweak_bake_arm", text="Bake Arm", icon="KEYFRAME")
row = tweak_box.row(align=True)
row.operator("dlm.tweak_add_leg", text="Add Leg", icon="CONSTRAINT_BONE")
row.operator("dlm.tweak_remove_leg", text="Remove Leg", icon="X")
row.operator("dlm.tweak_bake_leg", text="Bake Leg", icon="KEYFRAME")
row = tweak_box.row(align=True)
row.operator("dlm.tweak_add_both", text="Add Both", icon="CONSTRAINT_BONE")
row.operator("dlm.tweak_remove_both", text="Remove Both", icon="X")
row.operator("dlm.tweak_bake_both", text="Bake Both", icon="KEYFRAME")
row = tweak_box.row()
row.prop(props, "tweak_nla_track_name", text="NLA track")
row = tweak_box.row()
row.prop(props, "tweak_bake_post_clean", text="Post-clean after bake")
# Linked Libraries: header row (always), main box only when expanded
missing_count = sum(1 for lib in props.linked_libraries if lib.is_missing)
section_icon = "DISCLOSURE_TRI_DOWN" if props.linked_libraries_section_expanded else "DISCLOSURE_TRI_RIGHT"
+12
View File
@@ -59,3 +59,15 @@ class DynamicLinkManagerProperties(PropertyGroup):
type=bpy.types.Object,
poll=lambda self, obj: obj and obj.type == "ARMATURE",
)
# Tweak tools (bake frame range and post-clean)
tweak_nla_track_name: StringProperty(
name="NLA Track (bake range)",
description="If set, bake uses this NLA track on the replacement armature for frame range; else scene range",
default="",
)
tweak_bake_post_clean: BoolProperty(
name="Post-clean after bake",
description="Run action clean keyframes and graph decimate (error 0.001) after baking",
default=False,
)