diff --git a/core/frontend-devtools/public/locales/en/FrontendDevTools.json b/core/frontend-devtools/public/locales/en/FrontendDevTools.json index e297165a40c1..39489bee5c5b 100644 --- a/core/frontend-devtools/public/locales/en/FrontendDevTools.json +++ b/core/frontend-devtools/public/locales/en/FrontendDevTools.json @@ -490,6 +490,9 @@ }, "ChangeBackgroundColor": { "keyin": "fdt bgcolor" + }, + "RepositoryApi": { + "keyin": "fdt repo" } } } \ No newline at end of file diff --git a/core/frontend-devtools/src/FrontEndDevTools.ts b/core/frontend-devtools/src/FrontEndDevTools.ts index de1fa8390764..88540c163e28 100644 --- a/core/frontend-devtools/src/FrontEndDevTools.ts +++ b/core/frontend-devtools/src/FrontEndDevTools.ts @@ -21,7 +21,7 @@ import { } from "./tools/PlanarMaskTools"; import { ChangeCameraTool, ChangeEmphasisSettingsTool, ChangeFlashSettingsTool, ChangeHiliteModeTool, ChangeHiliteSettingsTool, DefaultTileSizeModifierTool, FadeOutTool, - FreezeSceneTool, SetAspectRatioSkewTool, ShowTileVolumesTool, Toggle3dManipulationsTool, ToggleDrawingGraphicsTool, ToggleSectionDrawingSpatialViewTool, + FreezeSceneTool, RepositoryApiTool, SetAspectRatioSkewTool, ShowTileVolumesTool, Toggle3dManipulationsTool, ToggleDrawingGraphicsTool, ToggleSectionDrawingSpatialViewTool, ToggleTileTreeReferencesTool, ToggleViewAttachmentBoundariesTool, ToggleViewAttachmentClipShapesTool, ToggleViewAttachmentsTool, ViewportAddRealityModel, ViewportTileSizeModifierTool, } from "./tools/ViewportTools"; @@ -157,6 +157,7 @@ export class FrontendDevTools { QueryScheduleScriptTool, RealityTransitionTool, ReorderMapLayers, + RepositoryApiTool, ReportWebGLCompatibilityTool, ReverseScheduleScriptTool, SaturationConfig, diff --git a/core/frontend-devtools/src/tools/ViewportTools.ts b/core/frontend-devtools/src/tools/ViewportTools.ts index 611b821aba3d..ab1552185def 100644 --- a/core/frontend-devtools/src/tools/ViewportTools.ts +++ b/core/frontend-devtools/src/tools/ViewportTools.ts @@ -607,3 +607,70 @@ export class ChangeCameraTool extends Tool { return this.run(camera); } } + +export class RepositoryApiTool extends Tool { + public static override get minArgs() { return 0; } + public static override get maxArgs() { return 1; } + public static override toolId = "RepositoryApi"; + + public override async run(url: string): Promise { + const vp = IModelApp.viewManager.selectedView; + if (!vp) { + return false; + } + + vp.displayStyle.attachRealityModel({ tilesetUrl: url }); + + return true; + } + + public override async parseAndRun(): Promise { + const itwinId = "d78c258c-1a6f-4abe-8339-13820ce0f975"; + const accessToken = ""; + const resources = await this.getResources(itwinId, accessToken); + if (!resources) { + return false; + } + const tilesetUrl = await this.getTilesetUrl(resources[0], accessToken); + if (!tilesetUrl) { + return false; + } + return this.run(tilesetUrl); + } + + // get all resources for an itwin + private async getResources(iTwinId: string, accessToken: string) { + const headers = { + "Authorization": accessToken, + "Accept": "application/vnd.bentley.itwin-platform.v1+json", + "Content-Type": "application/json", + "Prefer": "return=representation" + }; + + const url = `https://dev-connect-contextregistry.bentley.com/v1/itwins/${iTwinId}/repositories/resources`; + + try { + const response = await fetch(url, {headers}); + const result = await response.json(); + return result.repositories[0].resources; + } + catch { + return undefined; + } +} + +// get a tileset url for a specific resource +private async getTilesetUrl(resource: any, accessToken: string): Promise { + const headers = { + "Authorization": accessToken, + "Accept": "application/vnd.bentley.itwin-platform.v1+json", + "Content-Type": "application/json", + "Prefer": "return=representation" + }; + const split = resource.detailsUrl.split("/itwins/"); + const url = `https://dev-connect-contextregistry.bentley.com/v1/itwins/${split[1]}`; + const response = await fetch(url, {headers}); + const responseJson = await response.json(); + return responseJson.graphics.url; +} +} diff --git a/core/frontend/src/RealityDataSourceTilesetUrlImpl.ts b/core/frontend/src/RealityDataSourceTilesetUrlImpl.ts index 0888ae3edb84..fab4d2dfed73 100644 --- a/core/frontend/src/RealityDataSourceTilesetUrlImpl.ts +++ b/core/frontend/src/RealityDataSourceTilesetUrlImpl.ts @@ -26,6 +26,8 @@ export class RealityDataSourceTilesetUrlImpl implements RealityDataSource { /** For use by all Reality Data. For RD stored on PW Context Share, represents the portion from the root of the Azure Blob Container*/ private _baseUrl: string = ""; + private _queryParams: string = ""; + /** Construct a new reality data source. * @param props JSON representation of the reality data source */ @@ -71,6 +73,8 @@ export class RealityDataSourceTilesetUrlImpl implements RealityDataSource { // The tile's path root will need to be reinserted for child tiles to return a 200 private setBaseUrl(url: string): void { const urlParts = url.split("/"); + const queryParts = urlParts[urlParts.length - 1].split("?"); + this._queryParams = `?${queryParts[1]}`; urlParts.pop(); if (urlParts.length === 0) this._baseUrl = ""; @@ -107,7 +111,7 @@ export class RealityDataSourceTilesetUrlImpl implements RealityDataSource { /** Returns the tile URL. If the tile path is a full URL, it is returned as is. Otherwise, the base URL is prepended to the tile path. */ private getTileUrl(tilePath: string){ - return this.isValidURL(tilePath) ? tilePath : this._baseUrl + tilePath; + return this.isValidURL(tilePath) ? tilePath : this._baseUrl + tilePath + this._queryParams; } /**