@itwin/frontend-devtools
Version:
Debug menu and supporting UI widgets
151 lines • 6.51 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* 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