UNPKG

@itwin/frontend-devtools

Version:

Debug menu and supporting UI widgets

151 lines 6.51 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Tools */ import { assert, CompressedId64Set } from "@itwin/core-bentley"; import { RenderSchedule, } from "@itwin/core-common"; import { _scheduleScriptReference } from "@itwin/core-frontend"; import { copyStringToClipboard } from "../ClipboardUtilities"; import { parseArgs } from "./parseArgs"; import { DisplayStyleTool } from "./DisplayStyleTools"; /** Query the schedule script JSON from an element. * @beta */ export class QueryScheduleScriptTool extends DisplayStyleTool { _sourceId; _action = "copy"; _includeElementIds = false; _countElementIds = false; _expandElementIds = false; static toolId = "QueryScheduleScript"; static get minArgs() { return 0; } static get maxArgs() { return 3; } async parse(input, vp) { const args = parseArgs(input); this._sourceId = args.get("i") ?? vp.displayStyle[_scheduleScriptReference]?.sourceId; if (!this._sourceId) return false; const action = args.get("a") ?? ""; this._action = action.length > 0 && "b" === action[0].toLowerCase() ? "break" : "copy"; this._includeElementIds = this._countElementIds = this._expandElementIds = false; const ids = args.get("e"); if (ids && ids.length > 0) { switch (ids[0].toLowerCase()) { case "i": this._includeElementIds = true; break; case "c": this._includeElementIds = this._countElementIds = true; break; case "e": this._includeElementIds = this._expandElementIds = true; break; } } return true; } async execute(vp) { if (!this._sourceId || !this._action) return false; const opts = { displayStyle: { omitScheduleScriptElementIds: !this._includeElementIds }, renderTimeline: { omitScriptElementIds: !this._includeElementIds }, }; let script; const props = await vp.iModel.elements.loadProps(this._sourceId, opts); if (props.script) script = JSON.parse(props.script.script); else if (props.jsonProperties?.styles?.scheduleScript) script = props.jsonProperties.styles.scheduleScript; if (!script) return false; if (this._countElementIds || this._expandElementIds) { for (const model of script) { for (const elem of model.elementTimelines) { const elemIds = typeof elem.elementIds === "string" ? CompressedId64Set.decompressArray(elem.elementIds) : elem.elementIds; if (this._countElementIds) elem.elementIds = elemIds.length; else elem.elementIds = elemIds; } } } if (this._action === "break") debugger; // eslint-disable-line no-debugger else copyStringToClipboard(JSON.stringify(script, null, 2)); return true; } } function reverseTimeline(timeline, accept) { if (!timeline) return; const len = timeline.length; for (let i = 0; i < len; i++) { const timeEntry = timeline.getEntry(i); const valueEntry = timeline.getEntry(len - i - 1); assert(undefined !== timeEntry); assert(undefined !== valueEntry); accept(timeEntry.time, valueEntry); } } /** A tool that modifies the [RenderSchedule.Script]($common), if any, associated with the selected [Viewport]($frontend) such that the entries in each * of its [RenderSchedule.ElementTimeline]($common)s are reversed. * @beta */ export class ReverseScheduleScriptTool extends DisplayStyleTool { static toolId = "ReverseScheduleScript"; async execute(vp) { const script = vp?.displayStyle.scheduleScript; if (!script || script.modelTimelines.some((x) => x.omitsElementIds)) return false; const builder = new RenderSchedule.ScriptBuilder(); for (const modelTimeline of script.modelTimelines) { const modelBuilder = builder.addModelTimeline(modelTimeline.modelId); for (const elemTimeline of modelTimeline.elementTimelines) { const elemBuilder = modelBuilder.addElementTimeline(elemTimeline.elementIds); reverseTimeline(elemTimeline.visibility, (time, entry) => elemBuilder.addVisibility(time, entry.value, entry.interpolation)); reverseTimeline(elemTimeline.color, (time, entry) => elemBuilder.addColor(time, entry.value, entry.interpolation)); reverseTimeline(elemTimeline.transform, (time, entry) => elemBuilder.addTransform(time, entry.value, entry.components, entry.interpolation)); reverseTimeline(elemTimeline.cuttingPlane, (time, entry) => elemBuilder.addCuttingPlane(time, entry.value, entry.interpolation)); } } const scriptProps = builder.finish(); const newScript = RenderSchedule.Script.fromJSON(scriptProps); assert(undefined !== newScript); vp.displayStyle.scheduleScript = newScript; return true; } async parse() { return true; } } /** A tool that changes or removes the [RenderSchedule.Script]($common) associated with the selected [Viewport]($frontend). * @beta */ export class SetScheduleScriptTool extends DisplayStyleTool { static toolId = "SetScheduleScript"; static get minArgs() { return 0; } static get maxArgs() { return 1; } _script; async parse(args) { if (args.length === 0) return true; // clear schedule script. try { this._script = RenderSchedule.Script.fromJSON(JSON.parse(args[0])); } catch (ex) { if (ex instanceof Error) alert(ex.toString()); } return undefined !== this._script; } async execute(vp) { vp.displayStyle.scheduleScript = this._script; return true; } } //# sourceMappingURL=ScheduleScriptTools.js.map