Amp-Thread-ID: https://ampcode.com/threads/T-019f9d91-77c1-7206-a60f-ed6554ce92ab Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
80 lines
3.4 KiB
TypeScript
80 lines
3.4 KiB
TypeScript
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { APPLICATION_HEADLESS } from "../test/application.js";
|
|
import { APPLICATION_VERSION } from "../examples/blender/nodes/application.js";
|
|
import {
|
|
graphId,
|
|
linkId,
|
|
nodeId,
|
|
socketId,
|
|
type GraphDocument,
|
|
type GraphLink,
|
|
type GraphNode,
|
|
} from "@lib/core/types.js";
|
|
import { nullRecord } from "@lib/core/json.js";
|
|
|
|
const { materializeNode, save } = APPLICATION_HEADLESS;
|
|
const node = (
|
|
id: string,
|
|
typeId: Parameters<typeof materializeNode>[1],
|
|
position: { readonly x: number; readonly y: number },
|
|
size: { readonly x: number; readonly y: number },
|
|
options: { readonly label?: string; readonly collapsed?: boolean; readonly parentId?: string } = {},
|
|
): GraphNode => ({
|
|
...materializeNode(id, typeId, position),
|
|
size,
|
|
...(options.label === undefined ? {} : { label: options.label }),
|
|
...(options.collapsed === undefined ? {} : { collapsed: options.collapsed }),
|
|
...(options.parentId === undefined ? {} : { parentId: nodeId(options.parentId) }),
|
|
});
|
|
|
|
const nodes = [
|
|
node("frame", "fxnode.common.frame", { x: -550, y: 250 }, { x: 190, y: 270 }, { label: "Surface Controls" }),
|
|
node("value-expanded", "fxnode.shader.value", { x: 30, y: -55 }, { x: 140, y: 100 }, { parentId: "frame" }),
|
|
node(
|
|
"value-collapsed",
|
|
"fxnode.shader.value",
|
|
{ x: 30, y: -175 },
|
|
{ x: 140, y: 100 },
|
|
{ collapsed: true, parentId: "frame" },
|
|
),
|
|
node("math", "fxnode.shader.math", { x: -300, y: 170 }, { x: 160, y: 110 }),
|
|
node("noise", "fxnode.shader.noise-texture", { x: -100, y: 190 }, { x: 165, y: 130 }),
|
|
node("reroute", "fxnode.common.reroute", { x: 105, y: 55 }, { x: 140, y: 100 }),
|
|
node("principled", "fxnode.shader.principled-bsdf", { x: 165, y: 175 }, { x: 185, y: 125 }),
|
|
node("output", "fxnode.shader.material-output", { x: 405, y: 115 }, { x: 155, y: 100 }),
|
|
];
|
|
const byId = nullRecord(nodes.map((item) => [item.id, item]));
|
|
const link = (id: string, fromNodeId: string, fromKey: string, toNodeId: string, toKey: string): GraphLink => ({
|
|
id: linkId(id),
|
|
fromNodeId: byId[fromNodeId]!.id,
|
|
fromSocketId: socketId(`${fromNodeId}:${fromKey}`),
|
|
toNodeId: byId[toNodeId]!.id,
|
|
toSocketId: socketId(`${toNodeId}:${toKey}`),
|
|
muted: false,
|
|
extensions: {},
|
|
});
|
|
const links = [
|
|
link("link-1", "value-expanded", "value", "math", "a"),
|
|
link("link-2", "value-collapsed", "value", "math", "b"),
|
|
link("link-3", "math", "value", "noise", "scale"),
|
|
link("link-4", "noise", "factor", "reroute", "input"),
|
|
link("link-5", "reroute", "output", "principled", "roughness"),
|
|
link("link-6", "principled", "bsdf", "output", "surface"),
|
|
];
|
|
const document: GraphDocument = {
|
|
schemaVersion: 2,
|
|
graphId: graphId("phase-4-example"),
|
|
catalogVersion: APPLICATION_VERSION,
|
|
nodes: byId,
|
|
links: nullRecord(links.map((item) => [item.id, item])),
|
|
metadata: nullRecord([["description", "Deterministic fxnode browser baseline"]]),
|
|
};
|
|
const path = new URL("../examples/blender/initialLayout.json", import.meta.url);
|
|
const saved = save(document);
|
|
const { schemaVersion: _schemaVersion, ...layout } = saved;
|
|
const canonical = `${JSON.stringify({ ...layout, nodes: layout.nodes.map((node) => ({ ...node, known: true })) }, null, 2)}\n`;
|
|
if (process.argv.includes("--write")) writeFileSync(path, canonical);
|
|
else if (readFileSync(path, "utf8") !== canonical)
|
|
throw new Error("Blender fixture is not canonical; run npm run generate:blender-fixture");
|
|
else console.log("blender fixture verified");
|