UNPKG

@itwin/frontend-devtools

Version:

Debug menu and supporting UI widgets

200 lines • 9.86 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.InspectElementTool = void 0; /** @packageDocumentation * @module Tools */ const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const core_frontend_1 = require("@itwin/core-frontend"); const ClipboardUtilities_1 = require("../ClipboardUtilities"); const parseArgs_1 = require("./parseArgs"); /** Creates a readable text summary of a geometric element or geometry part. The keyin takes the following arguments, all of which are optional: * - `id=elementId,elementId,elementId` comma-separated list of element Ids where each `elementId` is a hexadecimal element Id such as "0x12cb"; * - `symbology=0|1` where 1 indicates detailed symbology information should be included in the output; * - `placement=0|1` where 1 indicates detailed geometric element placement should be included; and * - `verbosity=0|1|2` controlling the verbosity of the output for each geometric primitive in the geometry stream. Higher values = more detailed information. Note verbosity=2 can produce megabytes of data for certain types of geometric primitives like large meshes. * - `modal=0|1` where 1 indicates the output should appear in a modal dialog. * - `copy=0|1` where 1 indicates the output should be copied to the clipboard. Defaults to true. * - `refs=0|1` where 1 indicates that for geometry parts a list of all elements referencing that part should be included in the output. This is extremely computationally expensive. * If no id is specified, the tool runs in interactive mode: first operating upon the selection set (if any), then allowing the user to select additional elements. * @beta */ class InspectElementTool extends core_frontend_1.PrimitiveTool { static toolId = "InspectElement"; static get minArgs() { return 0; } static get maxArgs() { return 6; } _options = {}; _elementIds; _modal = false; _useSelection = false; _doCopy = false; _explodeParts = false; constructor(options, elementIds) { super(); if (undefined !== options) this._options = { ...options }; this._elementIds = elementIds; } setupAndPromptForNextAction() { this._useSelection = (undefined !== this.targetView && this.targetView.iModel.selectionSet.isActive); if (!this._useSelection) core_frontend_1.IModelApp.accuSnap.enableLocate(true); this.showPrompt(); } showPrompt() { core_frontend_1.CoreTools.outputPromptByKey(this._useSelection ? "ElementSet.Prompts.ConfirmSelection" : "ElementSet.Prompts.IdentifyElement"); } autoLockTarget() { } requireWriteableTarget() { return false; } async onUnsuspend() { this.showPrompt(); } async onPostInstall() { await super.onPostInstall(); if (undefined !== this._elementIds) this.process(this._elementIds).then(async () => { await this.onReinitialize(); }).catch((err) => { core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, err.toString())); }); else { this.setupAndPromptForNextAction(); } } async onDataButtonDown(ev) { if (this._useSelection) { if (undefined !== ev.viewport) { const ids = []; ev.viewport.iModel.selectionSet.elements.forEach((id) => { if (!core_bentley_1.Id64.isInvalid(id) && !core_bentley_1.Id64.isTransient(id)) ids.push(id); }); if (0 === ids.length) core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, core_frontend_1.CoreTools.translate("ElementSet.Error.NotSupportedElmType"))); else await this.process(ids); await this.onReinitialize(); return core_frontend_1.EventHandled.Yes; } } const hit = await core_frontend_1.IModelApp.locateManager.doLocate(new core_frontend_1.LocateResponse(), true, ev.point, ev.viewport, ev.inputSource); if (undefined === hit || !hit.isElementHit) return core_frontend_1.EventHandled.No; await this.process([hit.sourceId]); this.setupAndPromptForNextAction(); return core_frontend_1.EventHandled.No; } async onResetButtonUp(_ev) { await this.onReinitialize(); return core_frontend_1.EventHandled.No; } async onReinitialize() { if (this._useSelection || undefined !== this._elementIds) { await this.exitTool(); } else { await this.onRestartTool(); } } async onRestartTool() { const tool = new InspectElementTool(); if (!await tool.run()) return this.exitTool(); } async filterHit(hit, _out) { return hit.isElementHit ? core_frontend_1.LocateFilterStatus.Accept : core_frontend_1.LocateFilterStatus.Reject; } async process(elementIds) { const request = { elementIds, options: this._options, }; let messageDetails; try { let str = await core_common_1.IModelReadRpcInterface.getClientForRouting(this.iModel.routingContext.token).getGeometrySummary(this.iModel.getRpcProps(), request); if (this._explodeParts) { const regex = /^part id: (0x[a-f0-9]+)/gm; const partIds = new Set(); let match; while (null !== (match = regex.exec(str))) partIds.add(match[1]); if (partIds.size > 0) { request.elementIds = Array.from(partIds); str += `\npart ids: ${JSON.stringify(request.elementIds)}\n`; str += await core_common_1.IModelReadRpcInterface.getClientForRouting(this.iModel.routingContext.token).getGeometrySummary(this.iModel.getRpcProps(), request); } } if (this._doCopy) (0, ClipboardUtilities_1.copyStringToClipboard)(str); const brief = `Summary ${this._doCopy ? "copied to clipboard." : "complete."}`; messageDetails = new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Info, brief, str); if (this._modal) { const div = document.createElement("div"); const appendText = (toAppend) => { const txt = document.createElement("div"); txt.innerText = toAppend; div.append(txt); }; const lines = str.split("\n"); const maxLines = 30; let curLine = 0; for (const line of lines) { appendText(line); if (++curLine > maxLines) { appendText("..."); break; } } await core_frontend_1.IModelApp.notifications.openMessageBox(core_frontend_1.MessageBoxType.Ok, div, core_frontend_1.MessageBoxIconType.Information); } } catch (err) { messageDetails = new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, "Error occurred while generating summary", core_bentley_1.BentleyError.getErrorMessage(err)); } core_frontend_1.IModelApp.notifications.outputMessage(messageDetails); } async parseAndRun(...inputArgs) { const args = (0, parseArgs_1.parseArgs)(inputArgs); const ids = args.get("i"); if (undefined !== ids) this._elementIds = ids.split(","); const verbosity = args.getInteger("v"); if (undefined !== verbosity) { switch (verbosity) { case 0: this._options.geometryVerbosity = core_common_1.GeometrySummaryVerbosity.Basic; break; case 1: this._options.geometryVerbosity = core_common_1.GeometrySummaryVerbosity.Detailed; break; case 2: this._options.geometryVerbosity = core_common_1.GeometrySummaryVerbosity.Full; break; } } const symbology = args.getBoolean("s"); if (undefined !== symbology) this._options.verboseSymbology = symbology; const placement = args.getBoolean("p"); if (undefined !== placement) this._options.includePlacement = placement; const parts = args.getBoolean("r"); if (true === parts && undefined !== core_frontend_1.IModelApp.viewManager.selectedView) this._options.includePartReferences = core_frontend_1.IModelApp.viewManager.selectedView.view.is3d() ? "3d" : "2d"; const modal = args.getBoolean("m"); if (undefined !== modal) this._modal = modal; const doCopy = args.getBoolean("c"); if (undefined !== doCopy) this._doCopy = doCopy; this._explodeParts = true === args.getBoolean("e"); return this.run(); } } exports.InspectElementTool = InspectElementTool; //# sourceMappingURL=InspectElementTool.js.map