← TeiaViewer examples
Scene and objects

An undoable command

A Command with its _do and _undo, composing another command, in the undo history.

CreateCommand.ts
import { Command, SetObjectsVisibilityCommand, Viewer } from '@stereograph/teiaviewer';

/**
 * Shows only the given objects among the loaded ones, undoable: what changes the scene goes through
 * a `Command` (`_do`, `_undo`), executed into the viewer's undo history.
 */
export class IsolateObjectsCommand extends Command {
  readonly name = 'IsolateObjectsCommand';
  readonly isUndoable = true;
  private readonly _uuids: Set<string>;
  /** The command hiding the others, undone with this one. */
  private _hideOthers: SetObjectsVisibilityCommand | null = null;

  constructor(viewer: Viewer, uuids: Iterable<string>) {
    super(viewer);
    this._uuids = new Set(uuids);
  }

  protected override async _do(): Promise<void> {
    // The loaded objects are those of the BIM mesh controller.
    const others = this.viewer.scene.bimMeshController.getAllVisibleObjectUuids()
      .filter((uuid) => !this._uuids.has(uuid));
    this._hideOthers = new SetObjectsVisibilityCommand(this.viewer, others, false);
    // Part of this command: not in the history on its own.
    await this._hideOthers.execute({
      addToUndoHistory: false,
    });
  }

  protected override async _undo(): Promise<void> {
    await this._hideOthers?.undo({
      addToRedoHistory: false,
    });
  }
}

export async function isolateThenUndo(viewer: Viewer) {
  await new IsolateObjectsCommand(viewer, ['Mesh0', 'Mesh1']).execute();
  await viewer.commandHistory.undoLastCommand();
  await viewer.commandHistory.redoLastCommand();
}