From 038537186cb64e3224c7646ceae0c22ae85dd1b3 Mon Sep 17 00:00:00 2001 From: Nathan Date: Fri, 13 Mar 2026 15:45:07 -0600 Subject: [PATCH] scan ALL objects for constraints targeting orig --- ...3_20-29Z-retargeting-focus-object-issue.md | 161 ++++++++++++++++++ ops/migrator.py | 9 +- 2 files changed, 167 insertions(+), 3 deletions(-) diff --git a/.specstory/history/2026-03-13_20-29Z-retargeting-focus-object-issue.md b/.specstory/history/2026-03-13_20-29Z-retargeting-focus-object-issue.md index e663198..2aada1a 100644 --- a/.specstory/history/2026-03-13_20-29Z-retargeting-focus-object-issue.md +++ b/.specstory/history/2026-03-13_20-29Z-retargeting-focus-object-issue.md @@ -199,3 +199,164 @@ The code was inserted after the armature modifiers section and before the next f --- +_**User**_ + +summarize this change in 72 characters or less. + +--- + +_**Agent (model kimi-k2.5, mode Agent)**_ + +
Thought Process +The user wants a summary of the change I just made in 72 characters or less. This is the change I made to the migrator.py file where I added camera DOF focus_object retargeting. + +Let me think about a concise summary: +- Added camera DOF focus_object retargeting to migrator +- Camera DOF focus_object now retargets during migration +- Fix: camera DOF focus_object retargeted from orig to rep + +I need to keep it under 72 characters. Let me check: + +"Added camera DOF focus_object retargeting to migrator." = 50 characters - good! + +"Camera DOF focus_object now retargets during migration." = 55 characters - good! + +"Fix: camera DOF focus_object retargeted from orig to rep." = 58 characters - good! + +I'll go with something clear and concise.
+ +--- + +Added camera DOF focus_object retargeting to migrator run_retarg_relatives. + +--- + +_**User**_ + +I had another character whose eyes were constrained via `Copy Location` to the origchar, but retargrelatives didn't retarget this constraint. Let's make it do so. + +--- + +_**Agent (model kimi-k2.5, mode Agent)**_ + +
Thought Process +The user is saying that a character's eyes have a "Copy Location" constraint that targets the origchar, but the retargetrelatives function didn't retarget this constraint. Let me look at the `run_retarg_relatives` function to understand how it handles constraints and see what might be missing. + +Let me read the relevant parts of the migrator.py file to understand the current constraint handling logic.
+ +--- + +Let me examine the current constraint retargeting logic in `run_retarg_relatives`. + +--- + + +
Tool use: **read_file_v2** • Read file: T:/Dynamic-Link-Manager/ops/migrator.py + +
+
+ +--- + +
Thought Process +The current code looks for objects that either: +1. Have a parent that is the original armature +2. Have constraints where `c.target == orig` + +It then adds those objects to the `candidates` set and retargets their constraints. + +The issue is that the eyes are likely objects in the original character's hierarchy (children of the armature), so they get excluded by `candidates -= orig_hierarchy` on line 481. + +Looking at the candidates building logic: +- It starts with `rep_descendants` (objects under the replacement character) +- It adds objects that are parented to orig or have constraints targeting orig +- Then it removes `orig_hierarchy` (the original character and all its descendants) + +The eye objects are probably in the original character's hierarchy (children/descendants of the armature), so they get filtered out. + +The solution is to also scan ALL objects in the scene for constraints targeting orig, not just the candidates. The current logic only retargets constraints on the candidates set, which excludes objects in orig's hierarchy. + +Let me modify the function to retarget constraints on ALL objects, not just the candidates.
+ +--- + +I see the issue. The current code builds a `candidates` set and then filters out `orig_hierarchy` (line 481). The eyes are likely objects in the original character's hierarchy (children of the armature), so they get excluded and their constraints aren't retargeted. + +The fix is to scan ALL objects for constraints targeting orig, not just the candidates set. + +--- + + + +
Tool use: **edit_file_v2** • Edit file: T:/Dynamic-Link-Manager/ops/migrator.py + +
+ +
+ +--- + +
Thought Process +Good, I separated the constraint retargeting to scan all objects instead of just the candidates. This means that even objects in the original character's hierarchy (like eyes with Copy Location constraints) will have their constraints retargeted. + +Let me verify the change and check for any linter errors.
+ +--- + + +
+Tool use: **read_lints** + + +Parameters: + +```json +{ + "paths": [ + "T:/Dynamic-Link-Manager/ops/migrator.py" + ] +} +``` +Result: + +```json +{ + "linterErrorsByFile": [ + { + "relativeWorkspacePath": "T:/Dynamic-Link-Manager/ops/migrator.py" + } + ] +} +``` +Status: **completed** + + +
+
+ +--- + +
Thought Process +No linter errors. Let me verify the change looks correct.
+ +--- + + +
Tool use: **read_file_v2** • Read file: T:/Dynamic-Link-Manager/ops/migrator.py + +
+
+ +--- + +
Thought Process +The fix looks good. The constraint retargeting is now separate from the candidates loop and scans all objects in the scene. This means that even objects in the original character's hierarchy (like eyes with Copy Location constraints) will have their constraints retargeted properly.
+ +--- + +Fixed. The issue was that constraint retargeting was only applied to `candidates - orig_hierarchy`, which excluded objects in the original character's hierarchy (like eyes). + +Now the constraint retargeting (lines 490-494) scans ALL objects in the scene, so Copy Location constraints on eyes or any other object targeting the original armature will be properly retargeted to the replacement. + +--- + diff --git a/ops/migrator.py b/ops/migrator.py index 5285a81..497ac7a 100644 --- a/ops/migrator.py +++ b/ops/migrator.py @@ -482,14 +482,17 @@ 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 + # Camera DOF: retarget focus_object from orig to rep for ob in bpy.data.objects: if ob.type != 'CAMERA':