rm switch parent constraints

This commit is contained in:
2026-02-02 23:56:47 -07:00
parent c6ba8a2e64
commit a01c7a0791
2 changed files with 278 additions and 2 deletions

View File

@@ -7744,3 +7744,279 @@ Status: **completed**
---
_**User**_
moving the root appears to multiply the transforms of the IK controls; they move further than the actual transforms I input. What's with that?
---
_**Agent (model default, mode Agent)**_
Checking the IK target bones for constraints or parent chains that could cause transform multiplication:
---
<tool-use data-tool-type="unknown" data-tool-name="mcp-blender-user-blender-execute_blender_code">
<details>
<summary>Tool use: **mcp-blender-user-blender-execute_blender_code**</summary>
Parameters:
```json
{
"tools": [
{
"name": "execute_blender_code",
"parameters": "{\"code\":\"import bpy\\n\\narmature = bpy.context.active_object\\nif not armature or armature.type != 'ARMATURE':\\n for obj in bpy.context.scene.objects:\\n if obj.type == 'ARMATURE' and 'Vanessa' in obj.name:\\n armature = obj\\n break\\n\\nif armature:\\n bpy.context.view_layer.objects.active = armature\\n if armature.mode != 'POSE':\\n bpy.ops.object.mode_set(mode='POSE')\\n \\n print(\\\"=\\\"*60)\\n print(\\\"IK control bones - checking for transform multiplication\\\")\\n print(\\\"=\\\"*60 + \\\"\\\\n\\\")\\n \\n # The actual IK control bones (what user grabs)\\n ik_controls = [\\n 'hand_ik.L', 'hand_ik.R',\\n 'foot_ik.L', 'foot_ik.R',\\n 'thigh_ik_target.L', 'thigh_ik_target.R',\\n 'upper_arm_ik_target.L', 'upper_arm_ik_target.R',\\n ]\\n \\n for bone_name in ik_controls:\\n bone = armature.pose.bones.get(bone_name)\\n if bone:\\n print(f\\\"{bone_name}:\\\")\\n print(f\\\" Parent: {bone.parent.name if bone.parent else 'None'}\\\")\\n \\n # Trace parent chain to root\\n chain = []\\n current = bone.parent\\n while current and len(chain) &lt; 10:\\n chain.append(current.name)\\n current = current.parent\\n print(f\\\" Chain to root: {' -&gt; '.join(chain)}\\\")\\n \\n # Check constraints\\n if bone.constraints:\\n print(f\\\" Constraints:\\\")\\n for c in bone.constraints:\\n if c.enabled:\\n print(f\\\" - {c.type}: {c.name}\\\")\\n if hasattr(c, 'subtarget') and c.subtarget:\\n print(f\\\" target: {c.subtarget}\\\")\\n if c.type == 'COPY_TRANSFORMS':\\n print(f\\\" ⚠️ COPY_TRANSFORMS can cause double application if target is in same hierarchy!\\\")\\n else:\\n print(f\\\" No constraints\\\")\\n print()\",\"user_prompt\":\"User says moving root multiplies IK control transforms - they move further than input. Checking for double transform application.\"}",
"serverName": "blender"
}
]
}
```
Additional data:
```json
{
"status": "success"
}
```
Result:
```json
{
"result": "{\"content\":[{\"type\":\"text\",\"text\":\"Code executed successfully: ============================================================\\nIK control bones - checking for transform multiplication\\n============================================================\\n\\nhand_ik.L:\\n Parent: MCH-hand_ik.parent.L\\n Chain to root: MCH-hand_ik.parent.L -&gt; root\\n No constraints\\n\\nhand_ik.R:\\n Parent: MCH-hand_ik.parent.R\\n Chain to root: MCH-hand_ik.parent.R -&gt; root\\n No constraints\\n\\nfoot_ik.L:\\n Parent: MCH-foot_ik.parent.L\\n Chain to root: MCH-foot_ik.parent.L -&gt; root\\n No constraints\\n\\nfoot_ik.R:\\n Parent: MCH-foot_ik.parent.R\\n Chain to root: MCH-foot_ik.parent.R -&gt; root\\n No constraints\\n\\nthigh_ik_target.L:\\n Parent: MCH-thigh_ik_target.parent.L\\n Chain to root: MCH-thigh_ik_target.parent.L -&gt; root\\n No constraints\\n\\nthigh_ik_target.R:\\n Parent: MCH-thigh_ik_target.parent.R\\n Chain to root: MCH-thigh_ik_target.parent.R -&gt; root\\n No constraints\\n\\nupper_arm_ik_target.L:\\n Parent: MCH-upper_arm_ik_target.parent.L\\n Chain to root: MCH-upper_arm_ik_target.parent.L -&gt; root\\n No constraints\\n\\nupper_arm_ik_target.R:\\n Parent: MCH-upper_arm_ik_target.parent.R\\n Chain to root: MCH-upper_arm_ik_target.parent.R -&gt; root\\n No constraints\\n\\n\"}]}"
}
```
User decision: **accepted**
Status: **completed**
</details>
</tool-use>
---
Checking MCH parent bones for constraints that could cause double application:
---
<tool-use data-tool-type="unknown" data-tool-name="mcp-blender-user-blender-execute_blender_code">
<details>
<summary>Tool use: **mcp-blender-user-blender-execute_blender_code**</summary>
Parameters:
```json
{
"tools": [
{
"name": "execute_blender_code",
"parameters": "{\"code\":\"import bpy\\n\\narmature = bpy.context.active_object\\nif not armature or armature.type != 'ARMATURE':\\n for obj in bpy.context.scene.objects:\\n if obj.type == 'ARMATURE' and 'Vanessa' in obj.name:\\n armature = obj\\n break\\n\\nif armature:\\n bpy.context.view_layer.objects.active = armature\\n if armature.mode != 'POSE':\\n bpy.ops.object.mode_set(mode='POSE')\\n \\n print(\\\"=\\\"*60)\\n print(\\\"MCH IK parent bones - checking constraints\\\")\\n print(\\\"=\\\"*60 + \\\"\\\\n\\\")\\n \\n mch_parents = [\\n 'MCH-hand_ik.parent.L', 'MCH-hand_ik.parent.R',\\n 'MCH-foot_ik.parent.L', 'MCH-foot_ik.parent.R',\\n 'MCH-thigh_ik_target.parent.L', 'MCH-thigh_ik_target.parent.R',\\n 'MCH-upper_arm_ik_target.parent.L', 'MCH-upper_arm_ik_target.parent.R',\\n ]\\n \\n for bone_name in mch_parents:\\n bone = armature.pose.bones.get(bone_name)\\n if bone:\\n print(f\\\"{bone_name}:\\\")\\n print(f\\\" Parent: {bone.parent.name if bone.parent else 'None'}\\\")\\n \\n if bone.constraints:\\n for c in bone.constraints:\\n if c.enabled:\\n print(f\\\" Constraint: {c.type} - {c.name}\\\")\\n if hasattr(c, 'target') and c.target:\\n print(f\\\" Object: {c.target.name}\\\")\\n if hasattr(c, 'subtarget') and c.subtarget:\\n print(f\\\" Bone: {c.subtarget}\\\")\\n # Check if target bone is under root\\n target_bone = armature.pose.bones.get(c.subtarget)\\n if target_bone:\\n chain = []\\n p = target_bone.parent\\n while p and len(chain) &lt; 5:\\n chain.append(p.name)\\n p = p.parent\\n print(f\\\" Target chain: {' -&gt; '.join(chain)}\\\")\\n if hasattr(c, 'targets'):\\n for i, t in enumerate(c.targets):\\n if hasattr(t, 'subtarget') and t.subtarget:\\n print(f\\\" Target {i}: {t.subtarget}\\\")\\n else:\\n print(f\\\" No constraints\\\")\\n print()\\n \\n print(\\\"=\\\"*60)\\n print(\\\"Possible cause: SWITCH_PARENT constraints blend multiple parent\\\")\\n print(\\\"transforms. If root movement affects the blend, transforms can stack.\\\")\\n print(\\\"=\\\"*60)\",\"user_prompt\":\"Checking MCH IK parent bones for constraints that could cause transform multiplication when root moves.\"}",
"serverName": "blender"
}
]
}
```
Additional data:
```json
{
"status": "success"
}
```
Result:
```json
{
"result": "{\"content\":[{\"type\":\"text\",\"text\":\"Code executed successfully: ============================================================\\nMCH IK parent bones - checking constraints\\n============================================================\\n\\nMCH-hand_ik.parent.L:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n Target 5: ORG-shoulder.L\\n\\nMCH-hand_ik.parent.R:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n Target 5: ORG-shoulder.R\\n\\nMCH-foot_ik.parent.L:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n\\nMCH-foot_ik.parent.R:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n\\nMCH-thigh_ik_target.parent.L:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n Target 5: MCH-thigh_ik_target.L\\n\\nMCH-thigh_ik_target.parent.R:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n Target 5: MCH-thigh_ik_target.R\\n\\nMCH-upper_arm_ik_target.parent.L:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n Target 5: ORG-shoulder.L\\n Target 6: MCH-upper_arm_ik_target.L\\n\\nMCH-upper_arm_ik_target.parent.R:\\n Parent: root\\n Constraint: ARMATURE - SWITCH_PARENT\\n Target 0: root\\n Target 1: torso\\n Target 2: ORG-spine\\n Target 3: ORG-spine.003\\n Target 4: ORG-head\\n Target 5: ORG-shoulder.R\\n Target 6: MCH-upper_arm_ik_target.R\\n\\n============================================================\\nPossible cause: SWITCH_PARENT constraints blend multiple parent\\ntransforms. If root movement affects the blend, transforms can stack.\\n============================================================\\n\"}]}"
}
```
User decision: **accepted**
Status: **completed**
</details>
</tool-use>
---
Identifying the cause: SWITCH_PARENT constraints on the IK parent bones. They're parented to root and also blend root as a target, causing double application. Removing those SWITCH_PARENT constraints.
---
<tool-use data-tool-type="unknown" data-tool-name="mcp-blender-user-blender-execute_blender_code">
<details>
<summary>Tool use: **mcp-blender-user-blender-execute_blender_code**</summary>
Parameters:
```json
{
"tools": [
{
"name": "execute_blender_code",
"parameters": "{\"code\":\"import bpy\\n\\narmature = bpy.context.active_object\\nif not armature or armature.type != 'ARMATURE':\\n for obj in bpy.context.scene.objects:\\n if obj.type == 'ARMATURE' and 'Vanessa' in obj.name:\\n armature = obj\\n break\\n\\nif armature:\\n bpy.context.view_layer.objects.active = armature\\n if armature.mode != 'POSE':\\n bpy.ops.object.mode_set(mode='POSE')\\n \\n print(\\\"=\\\"*60)\\n print(\\\"Removing SWITCH_PARENT from IK target parents\\\")\\n print(\\\"(These cause double transform when root is both parent AND constraint target)\\\")\\n print(\\\"=\\\"*60 + \\\"\\\\n\\\")\\n \\n mch_parents = [\\n 'MCH-hand_ik.parent.L', 'MCH-hand_ik.parent.R',\\n 'MCH-foot_ik.parent.L', 'MCH-foot_ik.parent.R',\\n 'MCH-thigh_ik_target.parent.L', 'MCH-thigh_ik_target.parent.R',\\n 'MCH-upper_arm_ik_target.parent.L', 'MCH-upper_arm_ik_target.parent.R',\\n ]\\n \\n removed = 0\\n for bone_name in mch_parents:\\n bone = armature.pose.bones.get(bone_name)\\n if bone:\\n for constraint in list(bone.constraints):\\n if constraint.type == 'SWITCH_PARENT':\\n print(f\\\"Removing SWITCH_PARENT from {bone_name}\\\")\\n bone.constraints.remove(constraint)\\n removed += 1\\n print(f\\\" ✓\\\")\\n \\n print(f\\\"\\\\n✓ Removed {removed} SWITCH_PARENT constraint(s)\\\")\\n print(\\\"\\\\nIK controls will now move 1:1 with root (no multiplication).\\\")\\n print(\\\"=\\\"*60)\",\"user_prompt\":\"Removing SWITCH_PARENT constraints that cause transform multiplication - root is both parent and constraint target.\"}",
"serverName": "blender"
}
]
}
```
Additional data:
```json
{
"status": "success"
}
```
Result:
```json
{
"result": "{\"content\":[{\"type\":\"text\",\"text\":\"Code executed successfully: ============================================================\\nRemoving SWITCH_PARENT from IK target parents\\n(These cause double transform when root is both parent AND constraint target)\\n============================================================\\n\\n\\n✓ Removed 0 SWITCH_PARENT constraint(s)\\n\\nIK controls will now move 1:1 with root (no multiplication).\\n============================================================\\n\"}]}"
}
```
User decision: **accepted**
Status: **completed**
</details>
</tool-use>
---
Checking the constraint type — it may use a different name:
---
<tool-use data-tool-type="unknown" data-tool-name="mcp-blender-user-blender-execute_blender_code">
<details>
<summary>Tool use: **mcp-blender-user-blender-execute_blender_code**</summary>
Parameters:
```json
{
"tools": [
{
"name": "execute_blender_code",
"parameters": "{\"code\":\"import bpy\\n\\narmature = bpy.context.active_object\\nif not armature or armature.type != 'ARMATURE':\\n for obj in bpy.context.scene.objects:\\n if obj.type == 'ARMATURE' and 'Vanessa' in obj.name:\\n armature = obj\\n break\\n\\nif armature:\\n bpy.context.view_layer.objects.active = armature\\n if armature.mode != 'POSE':\\n bpy.ops.object.mode_set(mode='POSE')\\n \\n bone = armature.pose.bones.get('MCH-hand_ik.parent.L')\\n if bone and bone.constraints:\\n print(\\\"Constraints on MCH-hand_ik.parent.L:\\\")\\n for c in bone.constraints:\\n print(f\\\" Type: {c.type!r}\\\")\\n print(f\\\" Name: {c.name}\\\")\\n print(f\\\" Type (repr): {repr(type(c).__name__)}\\\")\\n \\n # Try removing by type - maybe it's ARMATURE or something else\\n print(\\\"\\\\n\\\" + \\\"=\\\"*60)\\n print(\\\"Removing constraints that have multiple targets (SWITCH_PARENT)...\\\")\\n print(\\\"=\\\"*60 + \\\"\\\\n\\\")\\n \\n mch_parents = [\\n 'MCH-hand_ik.parent.L', 'MCH-hand_ik.parent.R',\\n 'MCH-foot_ik.parent.L', 'MCH-foot_ik.parent.R',\\n 'MCH-thigh_ik_target.parent.L', 'MCH-thigh_ik_target.parent.R',\\n 'MCH-upper_arm_ik_target.parent.L', 'MCH-upper_arm_ik_target.parent.R',\\n ]\\n \\n removed = 0\\n for bone_name in mch_parents:\\n bone = armature.pose.bones.get(bone_name)\\n if bone:\\n for constraint in list(bone.constraints):\\n # SWITCH_PARENT or ARMATURE type with \\\"SWITCH\\\" in name\\n if 'SWITCH' in constraint.type or 'SWITCH' in constraint.name.upper():\\n print(f\\\"Removing {constraint.type}:{constraint.name} from {bone_name}\\\")\\n bone.constraints.remove(constraint)\\n removed += 1\\n elif hasattr(constraint, 'targets') and len(constraint.targets) &gt; 1:\\n # Constraint with multiple targets - likely the culprit\\n print(f\\\"Removing {constraint.type}:{constraint.name} from {bone_name} (has {len(constraint.targets)} targets)\\\")\\n bone.constraints.remove(constraint)\\n removed += 1\\n \\n print(f\\\"\\\\n✓ Removed {removed} constraint(s)\\\")\",\"user_prompt\":\"Checking actual constraint type and removing the ones causing multiplication.\"}",
"serverName": "blender"
}
]
}
```
Additional data:
```json
{
"status": "success"
}
```
Result:
```json
{
"result": "{\"content\":[{\"type\":\"text\",\"text\":\"Code executed successfully: Constraints on MCH-hand_ik.parent.L:\\n Type: 'ARMATURE'\\n Name: SWITCH_PARENT\\n Type (repr): 'ArmatureConstraint'\\n\\n============================================================\\nRemoving constraints that have multiple targets (SWITCH_PARENT)...\\n============================================================\\n\\nRemoving ARMATURE:SWITCH_PARENT from MCH-hand_ik.parent.L\\nRemoving ARMATURE:SWITCH_PARENT from MCH-hand_ik.parent.R\\nRemoving ARMATURE:SWITCH_PARENT from MCH-foot_ik.parent.L\\nRemoving ARMATURE:SWITCH_PARENT from MCH-foot_ik.parent.R\\nRemoving ARMATURE:SWITCH_PARENT from MCH-thigh_ik_target.parent.L\\nRemoving ARMATURE:SWITCH_PARENT from MCH-thigh_ik_target.parent.R\\nRemoving ARMATURE:SWITCH_PARENT from MCH-upper_arm_ik_target.parent.L\\nRemoving ARMATURE:SWITCH_PARENT from MCH-upper_arm_ik_target.parent.R\\n\\n✓ Removed 8 constraint(s)\\n\"}]}"
}
```
User decision: **accepted**
Status: **completed**
</details>
</tool-use>
---
**SWITCH_PARENT constraints removed**
**Cause:** The IK target parent bones used **ARMATURE** constraints named `SWITCH_PARENT` that blended several targets (root, torso, ORG-spine, etc.). Because they were also parented to root, root motion was applied twice: once from the parent and once from the constraint.
**Change:** Removed all 8 `SWITCH_PARENT` constraints from:
- `MCH-hand_ik.parent.L/R`
- `MCH-foot_ik.parent.L/R`
- `MCH-thigh_ik_target.parent.L/R`
- `MCH-upper_arm_ik_target.parent.L/R`
**Result:** These bones now only inherit from their parent (root), so IK controls should move 1:1 with the root without extra multiplication.
---
_**User**_
sorry, could you do that again? I was trying to move and ctrl z and it undid more than that
---
_**Agent (model default, mode Agent)**_
---
<tool-use data-tool-type="unknown" data-tool-name="mcp-blender-user-blender-execute_blender_code">
<details>
<summary>Tool use: **mcp-blender-user-blender-execute_blender_code**</summary>
Parameters:
```json
{
"tools": [
{
"name": "execute_blender_code",
"parameters": "{\"code\":\"import bpy\\n\\narmature = bpy.context.active_object\\nif not armature or armature.type != 'ARMATURE':\\n for obj in bpy.context.scene.objects:\\n if obj.type == 'ARMATURE' and 'Vanessa' in obj.name:\\n armature = obj\\n break\\n\\nif armature:\\n bpy.context.view_layer.objects.active = armature\\n if armature.mode != 'POSE':\\n bpy.ops.object.mode_set(mode='POSE')\\n \\n mch_parents = [\\n 'MCH-hand_ik.parent.L', 'MCH-hand_ik.parent.R',\\n 'MCH-foot_ik.parent.L', 'MCH-foot_ik.parent.R',\\n 'MCH-thigh_ik_target.parent.L', 'MCH-thigh_ik_target.parent.R',\\n 'MCH-upper_arm_ik_target.parent.L', 'MCH-upper_arm_ik_target.parent.R',\\n ]\\n \\n removed = 0\\n for bone_name in mch_parents:\\n bone = armature.pose.bones.get(bone_name)\\n if bone:\\n for constraint in list(bone.constraints):\\n if constraint.name == 'SWITCH_PARENT' or (hasattr(constraint, 'targets') and len(constraint.targets) &gt; 1):\\n bone.constraints.remove(constraint)\\n removed += 1\\n \\n print(f\\\"Removed {removed} SWITCH_PARENT constraint(s) from IK target parents\\\")\",\"user_prompt\":\"Redoing removal of SWITCH_PARENT constraints from IK target parent bones to fix transform multiplication.\"}",
"serverName": "blender"
}
]
}
```
Additional data:
```json
{
"status": "success"
}
```
Result:
```json
{
"result": "{\"content\":[{\"type\":\"text\",\"text\":\"Code executed successfully: Removed 8 SWITCH_PARENT constraint(s) from IK target parents\\n\"}]}"
}
```
User decision: **accepted**
Status: **completed**
</details>
</tool-use>
---
Removed the 8 SWITCH_PARENT constraints from the IK target parent bones again. Root movement should no longer multiply the IK control transforms.
---

Binary file not shown.