260 lines
9.4 KiB
Markdown
260 lines
9.4 KiB
Markdown
<!-- Generated by SpecStory, Markdown v2.1.0 -->
|
|
|
|
<!-- cursor Session 15ca8ebd-f444-47c7-8df3-efe4c9e8386f (2026-03-10 16:07Z) -->
|
|
|
|
# Reading content from migrator.py (2026-03-10 16:07Z)
|
|
|
|
_**User**_
|
|
|
|
Read the first 100 lines of the file T:\Dynamic-Link-Manager\ops\migrator.py and return the actual content. Use Python to read the file.
|
|
|
|
---
|
|
|
|
_**Agent (model accounts/fireworks/models/kimi-k2p5, mode Agent)**_
|
|
|
|
|
|
|
|
---
|
|
|
|
<think><details><summary>Thought Process</summary>
|
|
The user wants me to read the first 100 lines of a specific file using Python. Let me use the Shell tool to execute a Python command that reads the file.</details></think>
|
|
|
|
---
|
|
|
|
<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
|
|
<details><summary>Tool use: **run_terminal_command_v2** • Run command: python -c "
|
|
with open(r'T:\Dynamic-Link-Manager\ops\migrator.py', 'r') as f:
|
|
lines = f.readlines()[:100]
|
|
print(''.join(lines))
|
|
"</summary>
|
|
|
|
```bash
|
|
python -c "
|
|
with open(r'T:\Dynamic-Link-Manager\ops\migrator.py', 'r') as f:
|
|
lines = f.readlines()[:100]
|
|
print(''.join(lines))
|
|
"
|
|
```
|
|
|
|
```
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
|
|
"""Character migrator: migrate animation, constraints, relations from original to replacement armature."""
|
|
|
|
import bpy
|
|
|
|
from ..utils import descendants, collection_containing_armature
|
|
|
|
|
|
def get_pair_manual(context):
|
|
"""Return (orig_armature, rep_armature) from scene props, or (None, None)."""
|
|
props = getattr(context.scene, "dynamic_link_manager", None)
|
|
if not props:
|
|
return None, None
|
|
orig = getattr(props, "original_character", None)
|
|
rep = getattr(props, "replacement_character", None)
|
|
if orig and orig.type == "ARMATURE" and rep and rep.type == "ARMATURE":
|
|
return orig, rep
|
|
return None, None
|
|
|
|
|
|
def get_pair_automatic(context):
|
|
"""Discover one pair by convention: Name_Rigify and Name_Rigify.001. Returns (orig, rep) or (None, None)."""
|
|
pairs = []
|
|
for obj in bpy.data.objects:
|
|
if obj.type != "ARMATURE":
|
|
continue
|
|
name = obj.name
|
|
if name.endswith("_Rigify.001"):
|
|
base = name[:-len("_Rigify.001")]
|
|
orig = bpy.data.objects.get(f"{base}_Rigify")
|
|
if orig and orig.type == "ARMATURE" and orig != obj:
|
|
pairs.append((orig, obj))
|
|
return pairs[0] if pairs else (None, None)
|
|
|
|
|
|
def run_copy_attr(orig, rep):
|
|
"""Copy armature object attributes: location, rotation, scale (CopyAttr)."""
|
|
rep.location = orig.location.copy()
|
|
if orig.rotation_mode == "QUATERNION":
|
|
rep.rotation_quaternion = orig.rotation_quaternion.copy()
|
|
else:
|
|
rep.rotation_euler = orig.rotation_euler.copy()
|
|
rep.scale = orig.scale.copy()
|
|
|
|
|
|
def _has_als_anywhere(orig):
|
|
"""Return True if orig has Animation Layers (addon uses Object.als RNA PropertyGroup, obj.als.turn_on)."""
|
|
# Animation Layers addon: bpy.types.Object.als (RNA), not id props
|
|
if getattr(orig, "als", None) is not None:
|
|
return True
|
|
key = "als.turn_on"
|
|
if key in orig:
|
|
return True
|
|
if getattr(orig, "data", None) and hasattr(orig.data, "keys") and key in orig.data:
|
|
return True
|
|
try:
|
|
als = orig.get("als")
|
|
if als is not None and callable(getattr(als, "keys", None)) and "turn_on" in als.keys():
|
|
return True
|
|
except Exception:
|
|
pass
|
|
for pb in orig.pose.bones:
|
|
if key in pb:
|
|
return True
|
|
try:
|
|
als = pb.get("als")
|
|
if als is not None and callable(getattr(als, "keys", None)) and "turn_on" in als.keys():
|
|
return True
|
|
except Exception:
|
|
pass
|
|
return False
|
|
|
|
|
|
def _debug_als_lookup(orig):
|
|
"""Print full debug for AnimLayers: RNA obj.als and every id_prop on orig."""
|
|
key = "als.turn_on"
|
|
print("[DLM MigNLA] === AnimLayers debug ===")
|
|
als_rna = getattr(orig, "als", None)
|
|
print(f"[DLM MigNLA] orig.als (RNA): {als_rna!r}, turn_on={getattr(als_rna, 'turn_on', 'N/A') if als_rna else 'N/A'}")
|
|
print(f"[DLM MigNLA] 'als.turn_on' in orig (object): {key in orig}")
|
|
if getattr(orig, "data", None):
|
|
has_data_keys = hasattr(orig.data, "keys")
|
|
print(f"[DLM MigNLA] orig.data has keys(): {has_data_keys}")
|
|
if has_data_keys:
|
|
print(f"[DLM MigNLA] 'als.turn_on' in orig.data: {key in orig.data}")
|
|
print(f"[DLM MigNLA] orig.data keys: {list(orig.data.keys())}")
|
|
try:
|
|
als = orig.get("als")
|
|
has_als = als is not None and callable(getattr(als, "keys", None))
|
|
print(f"[DLM MigNLA] orig.get('als') is group: {has_als}")
|
|
if has_als:
|
|
print(f"[DLM MigNLA] orig['als'] keys: {list(als.keys())}")
|
|
print(f"[DLM MigNLA] 'turn_on' in orig['als']: {'turn_on' in als.keys()}")
|
|
except Exception as e:
|
|
print(f"[DLM MigNLA] orig.get('als') error: {e}")
|
|
print(f"[DLM MigNLA] orig (object) all keys: {list(orig.keys())}")
|
|
|
|
|
|
```
|
|
</details>
|
|
</tool-use>
|
|
|
|
---
|
|
|
|
<think><details><summary>Thought Process</summary>
|
|
The command executed successfully and returned the first 100 lines of the file. I should present this content to the user clearly.</details></think>
|
|
|
|
---
|
|
|
|
Here are the first 100 lines of `T:\Dynamic-Link-Manager\ops\migrator.py`:
|
|
|
|
```python
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
|
|
"""Character migrator: migrate animation, constraints, relations from original to replacement armature."""
|
|
|
|
import bpy
|
|
|
|
from ..utils import descendants, collection_containing_armature
|
|
|
|
|
|
def get_pair_manual(context):
|
|
"""Return (orig_armature, rep_armature) from scene props, or (None, None)."""
|
|
props = getattr(context.scene, "dynamic_link_manager", None)
|
|
if not props:
|
|
return None, None
|
|
orig = getattr(props, "original_character", None)
|
|
rep = getattr(props, "replacement_character", None)
|
|
if orig and orig.type == "ARMATURE" and rep and rep.type == "ARMATURE":
|
|
return orig, rep
|
|
return None, None
|
|
|
|
|
|
def get_pair_automatic(context):
|
|
"""Discover one pair by convention: Name_Rigify and Name_Rigify.001. Returns (orig, rep) or (None, None)."""
|
|
pairs = []
|
|
for obj in bpy.data.objects:
|
|
if obj.type != "ARMATURE":
|
|
continue
|
|
name = obj.name
|
|
if name.endswith("_Rigify.001"):
|
|
base = name[:-len("_Rigify.001")]
|
|
orig = bpy.data.objects.get(f"{base}_Rigify")
|
|
if orig and orig.type == "ARMATURE" and orig != obj:
|
|
pairs.append((orig, obj))
|
|
return pairs[0] if pairs else (None, None)
|
|
|
|
|
|
def run_copy_attr(orig, rep):
|
|
"""Copy armature object attributes: location, rotation, scale (CopyAttr)."""
|
|
rep.location = orig.location.copy()
|
|
if orig.rotation_mode == "QUATERNION":
|
|
rep.rotation_quaternion = orig.rotation_quaternion.copy()
|
|
else:
|
|
rep.rotation_euler = orig.rotation_euler.copy()
|
|
rep.scale = orig.scale.copy()
|
|
|
|
|
|
def _has_als_anywhere(orig):
|
|
"""Return True if orig has Animation Layers (addon uses Object.als RNA PropertyGroup, obj.als.turn_on)."""
|
|
# Animation Layers addon: bpy.types.Object.als (RNA), not id props
|
|
if getattr(orig, "als", None) is not None:
|
|
return True
|
|
key = "als.turn_on"
|
|
if key in orig:
|
|
return True
|
|
if getattr(orig, "data", None) and hasattr(orig.data, "keys") and key in orig.data:
|
|
return True
|
|
try:
|
|
als = orig.get("als")
|
|
if als is not None and callable(getattr(als, "keys", None)) and "turn_on" in als.keys():
|
|
return True
|
|
except Exception:
|
|
pass
|
|
for pb in orig.pose.bones:
|
|
if key in pb:
|
|
return True
|
|
try:
|
|
als = pb.get("als")
|
|
if als is not None and callable(getattr(als, "keys", None)) and "turn_on" in als.keys():
|
|
return True
|
|
except Exception:
|
|
pass
|
|
return False
|
|
|
|
|
|
def _debug_als_lookup(orig):
|
|
"""Print full debug for AnimLayers: RNA obj.als and every id_prop on orig."""
|
|
key = "als.turn_on"
|
|
print("[DLM MigNLA] === AnimLayers debug ===")
|
|
als_rna = getattr(orig, "als", None)
|
|
print(f"[DLM MigNLA] orig.als (RNA): {als_rna!r}, turn_on={getattr(als_rna, 'turn_on', 'N/A') if als_rna else 'N/A'}")
|
|
print(f"[DLM MigNLA] 'als.turn_on' in orig (object): {key in orig}")
|
|
if getattr(orig, "data", None):
|
|
has_data_keys = hasattr(orig.data, "keys")
|
|
print(f"[DLM MigNLA] orig.data has keys(): {has_data_keys}")
|
|
if has_data_keys:
|
|
print(f"[DLM MigNLA] 'als.turn_on' in orig.data: {key in orig.data}")
|
|
print(f"[DLM MigNLA] orig.data keys: {list(orig.data.keys())}")
|
|
try:
|
|
als = orig.get("als")
|
|
has_als = als is not None and callable(getattr(als, "keys", None))
|
|
print(f"[DLM MigNLA] orig.get('als') is group: {has_als}")
|
|
if has_als:
|
|
print(f"[DLM MigNLA] orig['als'] keys: {list(als.keys())}")
|
|
print(f"[DLM MigNLA] 'turn_on' in orig['als']: {'turn_on' in als.keys()}")
|
|
except Exception as e:
|
|
print(f"[DLM MigNLA] orig.get('als') error: {e}")
|
|
print(f"[DLM MigNLA] orig (object) all keys: {list(orig.keys())}")
|
|
```
|
|
|
|
---
|
|
|