feat(web): complete product workflow implementation
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

This commit is contained in:
mes123456
2026-09-06 08:33:27 +08:00
parent 7e3f6da78b
commit 1184a51ddf
39 changed files with 3736 additions and 160 deletions

View File

@@ -25,6 +25,8 @@ import type {
} from "./paint-stroke-session";
import type { PaintPBVHCapabilityRequest } from "./paint-pbvh-capability";
import type { LibraryMainAppendReceiptIR, LibraryMainAppendRequestIR } from "./library-main-append";
import type { BlenderOperatorDescriptor, BlenderOperatorPropertySpec, BlenderOperatorInvocation, BlenderOperatorPropertyValue } from "./blender-operator";
import type { SequencerTimelineIR } from "./sequencer";
export interface MeshGeometryBuffer {
schemaVersion: 1;
@@ -75,20 +77,28 @@ export interface MeshGeometryDelta {
}
export type MeshElementMode = "VERT" | "EDGE" | "FACE";
export type MeshEditOperation = "MERGE" | "DISSOLVE" | "EXTRUDE" | "INSET" | "BEVEL" | "LOOP_CUT";
export type MeshPrimitive = "CUBE" | "PLANE" | "UV_SPHERE" | "ICO_SPHERE" | "CYLINDER" | "CONE" | "TORUS";
export type MeshEditOperation = "MERGE" | "DISSOLVE" | "EXTRUDE" | "INSET" | "BEVEL" | "LOOP_CUT" | "SUBDIVIDE" | "FILL" | "TRIANGULATE" | "RECALCULATE_NORMALS" | "BRIDGE_LOOPS" | "DELETE";
export type FCurveInterpolation = "CONSTANT" | "LINEAR" | "BEZIER";
export type KeyframeHandle = [number, number];
export type WebEngineEditCommand =
| { type: "setFrame"; frame: number }
| { type: "setObjectVisibility"; objectId: string; visible: boolean }
| { type: "setModifierEnabled"; meshId: string; modifierUuid: string; enabled: boolean }
| { type: "setModifierVisibility"; meshId: string; modifierUuid: string; showViewport: boolean; showRender: boolean; showEditMode: boolean; showOnCage: boolean }
| { type: "addModifier"; meshId: string; modifierType: string; name?: string }
| { type: "removeModifier"; meshId: string; modifierUuid: string }
| { type: "moveModifier"; meshId: string; modifierUuid: string; direction?: "UP" | "DOWN"; index?: number }
| { type: "setModifierParameters"; meshId: string; modifierUuid: string; parameters: Record<string, unknown> }
| { type: "decimateMesh"; meshId: string; profile: SimplifyProfile }
| { type: "previewDecimateMesh"; meshId: string; profile: SimplifyProfile }
| { type: "createPrimitive"; primitive: "CUBE" | "PLANE"; name?: string; location: [number, number, number] }
| { type: "createPrimitive"; primitive: MeshPrimitive; name?: string; location: [number, number, number] }
| { type: "duplicateObject"; objectId: string; offset?: [number, number, number]; linked?: boolean }
| { type: "deleteObject"; objectId: string }
| { type: "setObjectTransform"; objectId: string; translation: [number, number, number]; rotationEuler: [number, number, number]; scale: [number, number, number] }
| { type: "setArmatureBones"; objectId: string; bones: Array<{ name: string; parentName: string | null; head: [number, number, number]; tail: [number, number, number]; roll: number; connected?: boolean }> }
| { type: "setPoseBoneTransform"; objectId: string; boneName: string; translation: [number, number, number]; rotationEuler: [number, number, number]; scale: [number, number, number] }
| { type: "translateMeshVertices"; meshId: string; vertexIndices: number[]; offset: [number, number, number] }
| { type: "meshEdit"; meshId: string; operation: MeshEditOperation; selectionMode: MeshElementMode; elementIndices: number[]; offset?: [number, number, number]; amount?: number; segments?: number }
| { type: "createUVMap"; meshId: string; name: string }
@@ -102,6 +112,10 @@ export type WebEngineEditCommand =
| { type: "setMaterialImageNode"; materialId: string; imageId: string; usage: "BASE_COLOR" | "NORMAL"; uvMap?: string }
| { type: "insertObjectKeyframe"; objectId: string; frame: number; property: "LOCATION" | "ROTATION_EULER" | "SCALE"; interpolation?: FCurveInterpolation }
| { type: "deleteObjectKeyframe"; objectId: string; frame: number; property?: "LOCATION" | "ROTATION_EULER" | "SCALE" }
| { type: "createAction"; name: string; objectId?: string }
| { type: "removeAction"; actionId: string }
| { type: "setKeyframe"; animationId: string; path: string; frame: number; value?: number[]; handleLeft?: KeyframeHandle; handleRight?: KeyframeHandle; interpolation?: FCurveInterpolation }
| { type: "setTimelineMarkers"; dataId: string; markers: Array<{ frame: number; name: string }> }
| { type: "setFCurveInterpolation"; animationId: string; path: string; interpolation: FCurveInterpolation }
| { type: "setActiveAction"; objectId: string; actionId: string | null }
| { type: "setConstraint"; objectId: string; constraintName: string; enabled: boolean; influence: number }
@@ -149,6 +163,7 @@ export type WebEngineEditCommand =
| { type: "setSceneUnitSettings"; dataId: string; properties: { system?: number; scaleLength?: number; rotationSystem?: number; lengthUnit?: number; massUnit?: number; timeUnit?: number; temperatureUnit?: number } }
| { type: "setSceneTimelineSettings"; dataId: string; properties: { fps?: number; fpsBase?: number; frameStep?: number; usePreviewRange?: boolean; previewStart?: number; previewEnd?: number } }
| { type: "setScenePipelineSettings"; dataId: string; properties: { useCompositor?: boolean; useSequencer?: boolean; noOverwrite?: boolean; saveOutput?: boolean; alphaPremultiplied?: boolean } }
| { type: "setSequencerStrips"; sceneId: string; timeline: SequencerTimelineIR }
| { type: "setSceneBindings"; dataId: string; properties: { cameraObjectId?: string | null; worldId?: string | null } }
| { type: "setSceneViewLayerSettings"; dataId: string; layerName: string; properties: { useRender?: boolean; useFreestyle?: boolean; samples?: number } }
| { type: "setSceneCollectionSettings"; dataId: string; layerName: string; collectionId: string; properties: { exclude?: boolean; holdout?: boolean; indirectOnly?: boolean; hide?: boolean } }
@@ -180,13 +195,33 @@ export type WebEngineEditCommand =
| { type: "undo" }
| { type: "redo" };
/** JSON values accepted by the allowlisted native operator bridge. */
export type WebEngineOperatorProperty = BlenderOperatorPropertyValue | null | WebEngineOperatorProperty[] | { [key: string]: WebEngineOperatorProperty };
export type WebEngineOperatorPropertySpec = BlenderOperatorPropertySpec;
export type WebEngineOperatorDescriptor = BlenderOperatorDescriptor;
export type WebEngineOperatorInvocation = BlenderOperatorInvocation;
/** Read-only commands supported by the stable Worker-to-WASM JSON facade. */
export type WebEngineJsonCommand =
| "snapshot"
| "delta"
| "depsgraph"
| "memoryStats"
| "applyCommand"
| "undo"
| "redo"
| "listBlenderOperators"
| "invokeBlenderOperator";
export type WebEngineRequest =
| { requestId: string; command: { type: "init" } }
| { requestId: string; command: { type: "loadWasmModule"; id: string } }
| { requestId: string; command: { type: "crashForTest" } }
| { requestId: string; command: { type: "openBlend"; buffer: ArrayBuffer }; }
| { requestId: string; command: { type: "cancelOpen"; targetRequestId: string } }
| { requestId: string; command: { type: "openResourceStatus" } }
| { requestId: string; command: { type: "snapshot" } }
| { requestId: string; command: { type: "jsonCommand"; cmd: WebEngineJsonCommand; params?: Record<string, unknown> } }
| { requestId: string; command: { type: "applyCommand"; payload: WebEngineEditCommand } }
| { requestId: string; command: { type: "appendLibraryObject"; request: LibraryMainAppendRequestIR; source: ArrayBuffer } }
| { requestId: string; command: { type: "beginPaintStroke"; session: PaintStrokeSessionBeginIR } }
@@ -262,12 +297,14 @@ export interface WebEngineResult {
lod?: WebEngineLODResult;
asset?: AssetRequestResult;
capabilityGate?: CapabilityGateResult;
json?: unknown;
shaderCompile?: ShaderCompileReport;
depsgraph?: DepsgraphEvaluationIR;
blend?: ArrayBuffer;
openResources?: WebEngineOpenResourceStatus;
paintStrokeSession?: PaintStrokeSessionReceiptIR;
libraryAppend?: LibraryMainAppendReceiptIR;
wasmModules?: Array<{ id: string; lifecycle: "complete" | "debug"; status: "pending" | "loaded" | "failed"; byteLength: number; error?: string }>;
}
export type WebEngineResponse =