# $viewer

The $viewer object can be accessed on any component instance (using this.$viewer), it is also passed as the first argument of the startupScript method of a plugin. It is the entrypoint to interact with the viewer core.

Below is a description of its interface:

interface $Viewer {
  readonly i18n: i18n;
  readonly api: Api;
  readonly state: State;
  readonly registeredWindows: string[];  // List of registered window names
  readonly registeredPlugins: string[];  // List of registered plugin names

  readonly globalContext: GlobalContext;
  readonly localContext: LocalContext;
  readonly contextMenu: ContextMenu;
}

# i18n

$viewer.i18n is used to access the viewer internationalization API:

enum ViewerLocale { "de", "en", "es", "fr", "it" }

interface i18n {
  i18nVuePlugin: any;
  registerTranslations(messages: Object): void;  // Register a set of messages
  changeLocale(locale: ViewerLocale): void;      // Change the current viewer locale
}

Example usage: register translations that will be used in a plugin template.

this.$viewer.i18n.registerTranslations({
  en: {
    hello: "Hello world !"
  },
  fr: {
    hello: "Boujour le monde !"
  }
});

# API

The $viewer.api object is used to interact with the BIMData API.

interface Api {
  readonly apiClient: BIMDataApiClient;
  readonly apiUrl: string;
  readonly archiveUrl: string;
  readonly cloudId: number;
  readonly projectId: number;
  readonly permissions: Permissions;
  accessToken: string;

  getModel(modelId: number): Promise<Model>;
  getModelStructure(model: Model): Promise<any>;
  getRawElements(modelId: number): Promise<any>;
  waitForModelProcess(model: Model): Promise<Model>;
}

TIP

See the doc of the typescript-fetch-api-client to learn more about what you can do with $viewer.api.apiClient.

Here is an example of how to get an IFC element from the API:

const modelId = 123;
const uuid = "my element uuid";

const element = await this.$viewer.api.apiClient.modelApi.getElement(
  this.$viewer.api.cloudId,
  modelId,
  this.$viewer.api.projectId,
  uuid
);

# Permissions

The $viewer.api.permissions object hold a set of flags that tell which actions the user is allowed to perform.

interface Permissions {
  hasAdminPermission: boolean;
  hasBcfReadPermission: boolean;
  hasBcfWritePermission: boolean;
  hasDocReadPermission: boolean;
  hasDocWritePermission: boolean;
  hasModelReadPermission: boolean;
  hasModelWritePermission: boolean;
  hasReadPermission: boolean;
  hasWritePermission: boolean;
  userRole: string;
  tokenScopes: {
    bcf?: string[];
    model?: string[];
    document?: string[];
  };
  usableScopes: {
    bcf?: string[];
    model?: string[];
    document?: string[];
  };
}

# getRawElements

The $viewer.api.getRawElements() method retrieves all objects, their properties, classifications, systems and layers.

For performance reasons, the API sends a formatted JSON that needs to be rebuilt in order to be used in javascript.

If you want to parse data to filter objects, you probably want to use this method.

const modelId = 123;
const elements = await this.$viewer.api.getRawElements(modelId);

The result is an object where keys are uuids and value are the element data formatted like the API response (opens new window).

# waitForModelProcess

The $viewer.api.waitForModelProcess() method can be used to wait until a given model is processed, i.e. it has a status of C (COMPLETED), E (ERROR) or X (WON'T FIX). It takes a model object as parameter.

A typical usage example is when you need to upload a model and then wait for it to be processed before opening it in a viewer.

const processedModel = await this.$viewer.api.waitForModelProcess(model);

# State

The $viewer.state object provide a way to interact with the global state.

# Global and Local contexts

The globalContext and the localContext objects are related to windows and the viewer UI in general. The globalContext is the whole UI while the localContext is the window where the code is executed.

A plugin must have a unique name in a window, but many plugins with the same name can be instanciated in the viewer if they belong to different windows. That is why globalContext.plugins.get(pluginName) returns an Array of plugins, while localContext.plugins.get(pluginName) returns a simple plugin.

For a more detailed description of the global/local context interfaces, refer to their respective documentation:

# Shortcuts

You can use globalContext/localContext to register shortcuts that depends on the context.

When triggering a shortcut, the current context is the window the mouse is hovering. If two shortcuts are registered on the same key, one on the localContext, the other on the globalContext, the localContext shortcut will be executed on keystroke if the mouse is hovering the window, else, it will be the globalContext one (the mouse is hovering another window or the header).

A shortcut object has the following interface:

interface Shortcut {
  name: string;       // [Required] A name to identify the shortcut.
  key: string;        // [Required] This key the shortcut is bound to (case insensitive).
  ctrlKey: boolean;   // [Default to `false`] Does the `ctrl` (or `meta`) key must be pressed to trigger the shortcut ?
  shiftKey: boolean;  // [Default to `false`] Does the `shift` key must be pressed to trigger the shortcut ?
  altKey: boolean;    // [Default to `false`] Does the `alt` key must be pressed to trigger the shortcut ?
  execute(): void;    // [Required] The function that will be executed when the key is pressed.
}

Example usage:

this.$viewer.globalContext.registerShortcut({
  name: "log",
  key: "l",
  ctrlKey: true,
  execute: () => console.log("Log from global shortcut."),
});

this.$viewer.localContext.registerShortcut({
  name: "log",
  key: "l",
  ctrlKey: true,
  execute: () => console.log("Log from local shortcut."),
});

Shortcuts can be unregistered calling the unregisterShortcut with the shortcut name.

this.$viewer.globalContext.unregisterShortcut("log");
this.$viewer.localContext.unregisterShortcut("log");

# Spinners

You can display a spinner to tell the user to wait until some process is finished.

Spinners can be displayed on the whole UI (globalContext) or just the current window (localContext).

// A spinner on the whole UI
this.$viewer.globalContext.loadingProcessStart();

// A spinner on the current window
this.$viewer.localContext.loadingProcessStart();

Global context spinner

Local context spinner

Viewer global context spinner Viewer local context spinner.

To stop spinners use the following methods:

this.$viewer.globalContext.loadingProcessEnd();
this.$viewer.localContext.loadingProcessEnd();

There is a loading property (on both globalContext and localContext) that indicates if a spinner is displayed on the related context.

The global spinner can also be customized via the setSpinner method:

// Set custom spinner to be used as global spinner
this.$viewer.globalContext.setSpinner({
  component: SpinnerComponent,
  props: SpinnerProps,
});

// Reset global spinner to default
this.$viewer.globalContext.setSpinner(null);

# Modals

In a similar way, you can choose to show a modal on the whole UI or just the current window using modals manager available on globalContext.modals and localContext.modals.

Modal manager allows to display modals. Modals are queued so if more than one modals are sent to the same modals manager, they will be displayed in order.

To open a modal, call pushModal on a modal manager.

Property Description
pushModal(component, props) Add a modal to the queue. component is a valid vuejs component. props is the component props values.
clearModal() Clear the current model.
this.$viewer.localContext.modals.pushModal(MyModalComponent);

To close a modal, click outside of its content or emit the "close" event inside the modal component.

this.$emit("close");

# Context Menu

You can manage the viewer context menu with $viewer.contextMenu.