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>
63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
import json
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
import bpy
|
|
|
|
|
|
def attribute_data(attribute):
|
|
values = []
|
|
for item in attribute.data:
|
|
if hasattr(item, "vector"):
|
|
values.append(list(item.vector))
|
|
elif hasattr(item, "color"):
|
|
values.append(list(item.color))
|
|
elif hasattr(item, "value"):
|
|
values.append(item.value)
|
|
return {"name": attribute.name, "domain": attribute.domain,
|
|
"dataType": attribute.data_type, "values": values}
|
|
|
|
|
|
def drawing_data(drawing):
|
|
return {
|
|
"attributes": [attribute_data(attribute) for attribute in drawing.attributes],
|
|
"strokes": [{
|
|
"cyclic": stroke.cyclic,
|
|
"materialIndex": stroke.material_index,
|
|
"points": [{
|
|
"position": list(point.position),
|
|
"radius": point.radius,
|
|
"opacity": point.opacity,
|
|
"vertexColor": list(point.vertex_color),
|
|
"select": point.select,
|
|
} for point in stroke.points],
|
|
} for stroke in drawing.strokes],
|
|
}
|
|
|
|
|
|
def snapshot():
|
|
return {
|
|
"objects": [{"name": obj.name, "data": obj.data.name,
|
|
"materials": [material.name if material else None
|
|
for material in obj.data.materials]}
|
|
for obj in sorted(bpy.data.objects, key=lambda item: item.name)
|
|
if obj.type == "GREASEPENCIL"],
|
|
"greasePencils": [{
|
|
"name": grease_pencil.name,
|
|
"layers": [{
|
|
"name": layer.name,
|
|
"frames": [{"frame": frame.frame_number,
|
|
"drawing": drawing_data(frame.drawing)}
|
|
for frame in layer.frames],
|
|
} for layer in grease_pencil.layers],
|
|
} for grease_pencil in sorted(bpy.data.grease_pencils_v3, key=lambda item: item.name)],
|
|
}
|
|
|
|
|
|
request = json.loads(Path(sys.argv[sys.argv.index("--") + 1]).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")
|