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
TypeScript
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;
}>;
}