import type { WebEngineEditCommand } from "./web-engine"; type NonMeshCommand = Extract; /** Typed constructors for non-mesh data, curve/surface topology, font, volume and Grease Pencil editing. */ export const nonMeshGeometryCommands = Object.freeze({ createCurve(name: string, controlPoints: readonly number[], cyclic = false, resolution = 12): NonMeshCommand<"createCurve"> { return { type: "createCurve", curveType: "CURVE", name, controlPoints: [...controlPoints], cyclic, resolution }; }, deleteNonMeshData(dataId: string): NonMeshCommand<"deleteNonMeshData"> { return { type: "deleteNonMeshData", dataId }; }, setCurveControlPoints(dataId: string, controlPoints: readonly number[], splineOffsets?: readonly number[], resolution?: number): NonMeshCommand<"setCurveControlPoints"> { return { type: "setCurveControlPoints", dataId, controlPoints: [...controlPoints], ...(splineOffsets ? { splineOffsets: [...splineOffsets] } : {}), ...(resolution === undefined ? {} : { resolution }) }; }, setCurveBevel(dataId: string, bevelDepth?: number, bevelResolution?: number, bevelFactorStart?: number, bevelFactorEnd?: number): NonMeshCommand<"setCurveBevel"> { return { type: "setCurveBevel", dataId, ...(bevelDepth === undefined ? {} : { bevelDepth }), ...(bevelResolution === undefined ? {} : { bevelResolution }), ...(bevelFactorStart === undefined ? {} : { bevelFactorStart }), ...(bevelFactorEnd === undefined ? {} : { bevelFactorEnd }) }; }, setCurveTaper(dataId: string, taperObjectId: string | null, taperRadiusMode?: number): NonMeshCommand<"setCurveTaper"> { return { type: "setCurveTaper", dataId, taperObjectId, ...(taperRadiusMode === undefined ? {} : { taperRadiusMode }) }; }, convertCurveType(dataId: string, targetType: "CURVE" | "SURFACE"): NonMeshCommand<"convertCurveType"> { return { type: "convertCurveType", dataId, targetType }; }, setCurveHandle(dataId: string, pointIndex: number, side: "LEFT" | "RIGHT", position: readonly [number, number, number]): NonMeshCommand<"setCurveHandle"> { return { type: "setCurveHandle", dataId, pointIndex, side, position: [...position] as [number, number, number] }; }, setCurveSplines( dataId: string, splineTypes: ReadonlyArray["splineTypes"][number]>, splineOffsets: readonly number[], ordersU: readonly number[], controlPoints: readonly number[], pointWeights: readonly number[], cyclicU: readonly boolean[], handleTypes: readonly number[], handlePoints: readonly number[], ): NonMeshCommand<"setCurveSplines"> { return { type: "setCurveSplines", dataId, splineTypes: [...splineTypes], splineOffsets: [...splineOffsets], ordersU: [...ordersU], controlPoints: [...controlPoints], pointWeights: [...pointWeights], cyclicU: [...cyclicU], handleTypes: [...handleTypes], handlePoints: [...handlePoints], }; }, setSurfaceTopology( dataId: string, splineDimensions: ReadonlyArray["splineDimensions"][number]>, controlPoints: readonly number[], pointWeights: readonly number[], cyclicU: readonly boolean[], cyclicV: readonly boolean[], ): NonMeshCommand<"setSurfaceTopology"> { return { type: "setSurfaceTopology", dataId, splineDimensions: splineDimensions.map((dimension) => ({ ...dimension })), controlPoints: [...controlPoints], pointWeights: [...pointWeights], cyclicU: [...cyclicU], cyclicV: [...cyclicV], }; }, setSurfaceResolution(dataId: string, resolutionU: number, resolutionV?: number): NonMeshCommand<"setSurfaceResolution"> { return { type: "setSurfaceResolution", dataId, resolutionU, ...(resolutionV === undefined ? {} : { resolutionV }) }; }, setFontBody(dataId: string, body: string): NonMeshCommand<"setFontBody"> { return { type: "setFontBody", dataId, body }; }, setFontProperties(dataId: string, properties: NonMeshCommand<"setFontProperties">["properties"]): NonMeshCommand<"setFontProperties"> { return { type: "setFontProperties", dataId, properties: { ...properties } }; }, setFontAdvanced( dataId: string, characters: ReadonlyArray["characters"][number]>, textBoxes: ReadonlyArray["textBoxes"][number]>, activeTextBox: number, ): NonMeshCommand<"setFontAdvanced"> { return { type: "setFontAdvanced", dataId, characters: characters.map((character) => ({ ...character })), textBoxes: textBoxes.map((textBox) => ({ ...textBox })), activeTextBox, }; }, importVFont(payload: Omit, "type">): NonMeshCommand<"importVFont"> { return { type: "importVFont", ...payload }; }, setFontLinks(dataId: string, links: NonMeshCommand<"setFontLinks">["links"]): NonMeshCommand<"setFontLinks"> { return { type: "setFontLinks", dataId, links: { ...links } }; }, setVolumeProperties(dataId: string, sourcePath: string, displayDensity: number, interpolation: "NEAREST" | "LINEAR", stepSize: number): NonMeshCommand<"setVolumeProperties"> { return { type: "setVolumeProperties", dataId, sourcePath, displayDensity, interpolation, stepSize }; }, setMetaballElements(dataId: string, elements: NonMeshCommand<"setMetaballElements">["elements"]): NonMeshCommand<"setMetaballElements"> { return { type: "setMetaballElements", dataId, elements: elements.map((element) => ({ ...element, position: [...element.position] as [number, number, number], scale: [...element.scale] as [number, number, number] })) }; }, createGreasePencilLayer(dataId: string, name: string): NonMeshCommand<"createGreasePencilLayer"> { return { type: "createGreasePencilLayer", dataId, name }; }, removeGreasePencilLayer(dataId: string, layerId: string): NonMeshCommand<"removeGreasePencilLayer"> { return { type: "removeGreasePencilLayer", dataId, layerId }; }, clearGreasePencilFrame(dataId: string, layerId: string, frame: number, baseRevision?: number): NonMeshCommand<"setGreasePencilStrokes"> { return { type: "setGreasePencilStrokes", dataId, layerId, frame, ...(baseRevision === undefined ? {} : { baseRevision }), strokes: [] }; }, } satisfies Record WebEngineEditCommand>);