UNPKG

forma-embedded-view-sdk

Version:

The Forma Embedded View SDK is a JavaScript library for creating custom extensions in Autodesk Forma (previously Spacemaker).

261 lines (260 loc) 9.11 kB
import type { FormaElement, Transform, Urn } from "forma-elements"; import type { IframeMessenger } from "./iframe-messenger.js"; import { RepresentationsApi } from "./representations.js"; /** * Response format when fetching elements. * * The Urn and FormaElement types can be inspected in the TypeScript type definitions * in your local IDE. */ export type ElementResponse = Record<Urn, FormaElement>; /** * The Elements API allows you to read all elements and create in a selection of Forma elements systems. * * @remarks * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.elements | elements}. */ export declare class ElementsApi { #private; floorStack: FloorStackApi; representations: RepresentationsApi; blobs: BlobsApi; /** @hidden */ constructor(iframeMessenger: IframeMessenger); /** * Get an element by urn. * * The method can return multiple elements. This can happen * if the element has children that are bundled with it. * * This method can also be used to include all the transitive children of the element * by setting the recursive parameter to true. * * @example * // Get the root element of the current proposal * const urn = await Forma.proposal.getRootUrn() * const { element, elements } = await Forma.elements.get({ urn }) * * @returns * A map from identifiers to elements. * A single element for the requested element */ get(request: { urn: Urn; recursive?: boolean; }): Promise<{ element: FormaElement; elements: ElementResponse; }>; /** * Get an element hierarchy located at the path relative to the current * root. You default to current proposal by omitting the urn parameter. * * @example * // Get all the building elements of the current proposal * Forma.selection.subscribe(({ paths }) => { * const { element, elements } = await Forma.elements.getByPath({ path: paths[0] }) * }); * * @returns * A map from identifiers to elements. */ getByPath(request: { rootUrn?: Urn; path: string; recursive?: boolean; }): Promise<{ element: FormaElement; elements: ElementResponse; }>; /** * Get the world transform of an element relative to the root element. * * The world transform is the affine transformation matrix that transforms * the element from its local coordinate system to the root coordinate system. * * @example * const { transform } = await Forma.elements.getWorldTransform({ path }) * const { element } = await Forma.elements.getByPath({ path }) * * if (element.representations?.footprint) { * const footprint = await Forma.elements.representations.footprint(element) * * const { data: geojson } = footprint * * void Forma.render.geojson.add({ geojson, transform }) * } * * @param request the path to element from root * @returns The affine transformation matrix of the element */ getWorldTransform(request: { path: string; }): Promise<{ transform: Transform; }>; /** * Allows adding, editing and removing custom properties attached directly to elements. * All properties must live under a namespace which follows `\w{1,20}:\w{1,50}` pattern (e.g.`my:namespace`). * The properties are managed by [JSON Merge Patch](https://datatracker.ietf.org/doc/html/rfc7386) specification. * * Requires edit access to the project. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @example * // Add two properties within a namespace to an element and replace its previous urn with the updated urn in a proposal * const addTwoProperties = { * "my:namespace": { * "myFirstProperty": "myFirstValue" * "mySecondProperty": "mySecondValue" * } * } * const result = await Forma.elements.editProperties({urn, propertiesJsonMergePatch: myProperties}); * await Forma.proposal.replaceElement({path, urn: result.urn}) * * @example * // Change value of the first property and remove the second property at the same time * const changeFirstRemoveSecondProperty = { * "my:namespace": { * "myFirstProperty": "veryDifferentValue" * "mySecondProperty": null * } * } * const result = await Forma.elements.editProperties({urn, propertiesJsonMergePatch: changeFirstRemoveSecondProperty}); * await Forma.proposal.replaceElement({path, urn: result.urn}) * * @example * // Remove the whole namespace from the element * const removeWholeNamespace = { * "my:namespace": null * } * const result = await Forma.elements.editProperties({urn, propertiesJsonMergePatch: removeWholeNamespace}); * await Forma.proposal.replaceElement({path, urn: result.urn}) * */ editProperties(request: { urn: Urn; propertiesJsonMergePatch: Record<string, Record<string, any> | null>; }): Promise<{ urn: Urn; }>; } /** A floor represented as an extruded polygon*/ export type Floor = { /** * The footprint of the floor. Must be a counterclockwise polygon. */ polygon: [number, number][]; /** * The height of the floor. Must be a positive number. */ height: number; }; /** * API for creating Floor Stack buildings. * * You can use this API together with the Forma.proposal.addElement * API to create a building and add it to a the current proposal. * * @example * // Create a building with 3 floors with a 2 meter setback * // Place it where the user clicks in the scene * const { urn } = await Forma.elements.floorStack.createFromFloors({ * floors: [ * { * polygon: [ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0] ], * height: 3, * }, * { * polygon: [ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0] ], * height: 2.6, * }, * { * polygon: [ [0, 0], [10, 0], [10, 8], [0, 8], [0, 0] ], * height: 2.6, * }, * ], * }) * const point = await Forma.designTool.getPoint() * if (!point) return * const transform = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, point.x, point.y, point.z, 1] * await Forma.proposal.addElement({ urn, transform }); * * @remarks * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.elements | elements}.{@link elements.ElementsApi.floorStack | floorStack}. */ export declare class FloorStackApi { #private; /** @hidden */ constructor(iframeMessenger: IframeMessenger); /** * Create a 2.5D building from a stack of floors. * * By 2.5D, we mean that the building only has vertical walls and flat roofs. * The floors are given from bottom to top. * * Requires edit access to the project. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @returns URN of the created building element. */ createFromFloors(request: { /** The floors which define the building */ floors: Floor[]; }): Promise<{ urn: string; }>; /** * Create multiple 2.5D buildings from stacks of floors. * * By 2.5D, we mean that the building only has vertical walls and flat roofs. * The floors are given from bottom to top. * * Requires edit access to the project. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info. * * @returns URNs of the created building elements. */ createFromFloorsBatch(request: { /** The floors which define the building */ floors: Floor[]; }[]): Promise<{ urns: string[]; }>; } /** * The Blobs API allows you to read blobs related to an element * * @remarks * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.elements | elements}.{@link elements.ElementsApi.blobs | blobs}. */ export declare class BlobsApi { #private; /** @hidden */ constructor(iframeMessenger: IframeMessenger); /** * Retrieve a blob by its id. * * Blobs are binary data that can be used for various purposes. * A common use case is together with linked representations * * @example * ```typescript * const { element } = await Forma.elements.get({ * urn: "urn:adsk-forma-elements:terrain:pro_cnusxrl4s1:c418dafe-1963-4160-9df5-239a49eef10b:1716818829774", * }) * * if (element.representations?.volumeMesh?.type === "linked") { * const blobResponse = await Forma.elements.blobs.get({ * blobId: element.representations.volumeMesh.blobId, * }) * const arrayBuffer: ArrayBuffer = blobResponse.data * } * ``` * * @returns an object containing the ArrayBuffer of the blob as data */ get(request: { /** BlobId of the blob you want. For example found through a linked representation */ blobId: string; }): Promise<{ data: ArrayBuffer; }>; }