2026-03-16
This commit is contained in:
@@ -482,14 +482,36 @@ def run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep):
|
||||
for ob in candidates:
|
||||
if ob.parent == orig:
|
||||
ob.parent = rep
|
||||
for c in getattr(ob, "constraints", []):
|
||||
if getattr(c, "target", None) == orig:
|
||||
c.target = rep
|
||||
if ob.type == "MESH" and ob.modifiers:
|
||||
for m in ob.modifiers:
|
||||
if getattr(m, "object", None) == orig:
|
||||
m.object = rep
|
||||
|
||||
# Retarget constraints on ALL objects (including orig hierarchy like eyes)
|
||||
for ob in bpy.data.objects:
|
||||
for c in getattr(ob, "constraints", []):
|
||||
if getattr(c, "target", None) == orig:
|
||||
c.target = rep
|
||||
|
||||
# Retarget bone constraints on ALL armatures (other characters, etc.)
|
||||
for ob in bpy.data.objects:
|
||||
if ob.type != "ARMATURE" or not ob.pose:
|
||||
continue
|
||||
for pbone in ob.pose.bones:
|
||||
for c in pbone.constraints:
|
||||
if getattr(c, "target", None) == orig:
|
||||
c.target = rep
|
||||
|
||||
# Camera DOF: retarget focus_object from orig to rep
|
||||
for ob in bpy.data.objects:
|
||||
if ob.type != 'CAMERA':
|
||||
continue
|
||||
camera = ob.data
|
||||
if not camera.dof:
|
||||
continue
|
||||
if camera.dof.focus_object == orig:
|
||||
camera.dof.focus_object = rep
|
||||
|
||||
|
||||
def _base_body_name_match(ob):
|
||||
"""True if object looks like the base body mesh (MESH, name has body+base)."""
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
"""Tweak tools: add/remove/bake COPY_TRANSFORMS on Rigify arm/leg tweak bones."""
|
||||
"""Tweak tools: add/remove/bake COPY_TRANSFORMS on Rigify tweak bones (arm, leg, or all)."""
|
||||
|
||||
import bpy
|
||||
|
||||
@@ -22,7 +22,7 @@ TWEAK_CONSTRAINT_NAME = "Copy from Original"
|
||||
|
||||
|
||||
def get_tweak_bones(armature, limb):
|
||||
"""Return list of tweak bone names that exist on armature. limb in 'arm', 'leg', 'both'."""
|
||||
"""Return list of tweak bone names that exist on armature. limb in 'arm', 'leg', 'body', 'both'."""
|
||||
if not armature or armature.type != "ARMATURE" or not armature.pose:
|
||||
return []
|
||||
bones = armature.pose.bones
|
||||
@@ -30,8 +30,20 @@ def get_tweak_bones(armature, limb):
|
||||
names = ARM_TWEAK_BONES
|
||||
elif limb == "leg":
|
||||
names = LEG_TWEAK_BONES
|
||||
elif limb == "body":
|
||||
# Body/torso tweaks: tweak_spine, spine_fk, etc. (no arm/leg)
|
||||
arm_leg_names = set(ARM_TWEAK_BONES + LEG_TWEAK_BONES)
|
||||
names = [
|
||||
b.name for b in bones
|
||||
if ("tweak" in b.name.lower() or "spine_fk" in b.name.lower())
|
||||
and b.name not in arm_leg_names
|
||||
]
|
||||
elif limb == "both":
|
||||
names = ARM_TWEAK_BONES + LEG_TWEAK_BONES
|
||||
# ALL tweak bones: any bone with "tweak" or "spine_fk" in the name
|
||||
names = [
|
||||
b.name for b in bones
|
||||
if "tweak" in b.name.lower() or "spine_fk" in b.name.lower()
|
||||
]
|
||||
else:
|
||||
return []
|
||||
return [n for n in names if n in bones]
|
||||
@@ -101,7 +113,7 @@ def bake_tweak_constraints(context, orig, rep, limb, track_name, post_clean):
|
||||
# Select only tweak bones on rep
|
||||
bpy.ops.pose.select_all(action="DESELECT")
|
||||
for name in names:
|
||||
rep.pose.bones[name].bone.select = True
|
||||
rep.pose.bones[name].select = True
|
||||
|
||||
# Bake
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user