Files
workinf_Blender_Wasm/web/tests/fixtures/animation-authoring-main-snapshots.py
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

107 lines
4.0 KiB
Python

import json
from pathlib import Path
import sys
import bpy
def curves_of(action):
curves = []
if hasattr(action, "fcurves"):
curves.extend(action.fcurves)
for layer in action.layers:
for strip in layer.strips:
for bag in getattr(strip, "channelbags", []):
curves.extend(bag.fcurves)
return curves
def curve_data(curve):
driver = curve.driver
return {
"path": curve.data_path,
"index": curve.array_index,
"group": curve.group.name if curve.group else None,
"driver": None if driver is None else {
"type": driver.type,
"expression": driver.expression,
"variables": [variable.name for variable in driver.variables],
},
"keys": [{
"co": list(key.co),
"left": list(key.handle_left),
"right": list(key.handle_right),
"leftType": key.handle_left_type,
"rightType": key.handle_right_type,
"interpolation": key.interpolation,
} for key in curve.keyframe_points],
}
def snapshot():
result = {
"actions": [{
"name": action.name,
"curves": sorted([curve_data(curve) for curve in curves_of(action)],
key=lambda curve: (curve["path"], curve["index"])),
"legacyGroups": [group.name for group in getattr(action, "groups", [])],
"slotGroups": [{
"slot": bag.slot_handle,
"groups": [group.name for group in bag.groups],
} for layer in action.layers for strip in layer.strips
for bag in getattr(strip, "channelbags", [])],
} for action in sorted(bpy.data.actions, key=lambda item: item.name)],
"objects": [{
"name": obj.name,
"action": obj.animation_data.action.name
if obj.animation_data and obj.animation_data.action else None,
"drivers": [curve_data(curve) for curve in obj.animation_data.drivers]
if obj.animation_data else [],
"location": list(obj.location),
} for obj in sorted(bpy.data.objects, key=lambda item: item.name)],
"scenes": [{
"name": scene.name,
"frame": scene.frame_current,
"activeKeyingSet": scene.keying_sets.active.bl_label
if scene.keying_sets.active else None,
"keyingSets": [{
"name": keying_set.bl_label,
"idname": keying_set.bl_idname,
"isPathAbsolute": keying_set.is_path_absolute,
"paths": [{
"path": item.data_path,
"arrayIndex": item.array_index,
"id": item.id.name if item.id else None,
"idType": item.id_type,
} for item in keying_set.paths],
} for keying_set in scene.keying_sets],
} for scene in sorted(bpy.data.scenes, key=lambda item: item.name)],
}
frames = []
scene = bpy.context.scene
original_frame = scene.frame_current
for frame in [1, 3, 5]:
scene.frame_set(frame)
evaluated = bpy.context.evaluated_depsgraph_get()
frames.append({
"frame": frame,
"objects": [{
"name": obj.name,
"location": list(obj.evaluated_get(evaluated).location),
"rotation": list(obj.evaluated_get(evaluated).rotation_euler),
"scale": list(obj.evaluated_get(evaluated).scale),
} for obj in sorted(bpy.data.objects, key=lambda item: item.name)],
})
scene.frame_set(original_frame)
result["evaluatedSamples"] = frames
return result
request_path = Path(sys.argv[sys.argv.index("--") + 1])
request = json.loads(request_path.read_text())
result = {}
for label, filename in request["files"].items():
bpy.ops.wm.open_mainfile(filepath=str(Path(filename).resolve()))
result[label] = snapshot()
Path(request["output"]).write_text(json.dumps(result, sort_keys=True, indent=2) + "\n")