Skip to content

Commit

Permalink
condense code, update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jjspace committed Nov 22, 2024
1 parent d2055b2 commit 47e1642
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 54 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
##### Additions :tada:

- Added `Entity.trackingReferenceFrame` property to allow tracking entities in their own inertial reference frame. [#12194](https://github.com/CesiumGS/cesium/pull/12194)
- Added a new integration with the iTwin Platform to easily load iModels directly in the viewer. Use `ITwinPlatform.defaultAccessToken` to set the access token then use `ITwinData.createTilesetFromIModelId(iModelId)` to load the iModel as a `Cesium3DTileset`. [#12289](https://github.com/CesiumGS/cesium/pull/12289)

##### Fixes :wrench:

Expand Down
23 changes: 12 additions & 11 deletions packages/engine/Source/Core/ITwinPlatform.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,22 @@ ITwinPlatform.apiEndpoint = new Resource({

/**
* @typedef {Object} ExportRequest
* @private
* @property {string} iModelId
* @property {string} changesetId
* @property {ITwinPlatform.ExportType} exportType Type of the export. CesiumJS only supports the 3DTILES type
*/

/**
* @typedef {Object} Link
* @private
* @property {string} href
*/

/**
* @typedef {Object} ExportRepresentation
* The export objects from get-exports when using return=representation
* @private
* @property {string} id Export id
* @property {string} displayName Name of the iModel
* @property {ITwinPlatform.ExportStatus} status Status of this export
Expand All @@ -81,24 +84,21 @@ ITwinPlatform.apiEndpoint = new Resource({

/**
* @typedef {Object} GetExportsResponse
* @private
* @property {ExportRepresentation[]} exports The list of exports for the current page
* @property {{self: Link, next: Link | undefined, prev: Link | undefined}} _links Pagination links
*/

/**
* Get the list of exports for the specified iModel at it's most current version. This will only return exports with {@link ITwinPlatform.ExportType} of <code>3DTILES</code>.
* Get the list of exports for the specified iModel at it's most current version.
* This will only return the top 5 exports with {@link ITwinPlatform.ExportType} of <code>3DTILES</code>.
*
* @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
* @private
*
* @param {string} iModelId iModel id
*
* @throws {RuntimeError} Unauthorized, bad token, wrong scopes or headers bad.
* @throws {RuntimeError} Not allowed, forbidden
* @throws {RuntimeError} Unprocessable Entity
* @throws {RuntimeError} Too many requests
* @throws {RuntimeError} Unknown request failure
* @returns {Promise<GetExportsResponse>}
*
* @throws {RuntimeError} If the iTwin API request is not successful
*/
ITwinPlatform.getExports = async function (iModelId) {
//>>includeStart('debug', pragmas.debug);
Expand All @@ -118,9 +118,10 @@ ITwinPlatform.getExports = async function (iModelId) {
queryParameters: {
iModelId: iModelId,
exportType: ITwinPlatform.ExportType["3DTILES"],
// TODO: If we're only requesting the top 1 is there a chance it's `Invalid` instead of `Complete`
// and never possible to load it?
$top: "1",
// With the export auto-generation it will auto-delete the 6th export so
// there should never be more than 5 results. Just request them all and parse
// for ones that are COMPLETE
$top: "5",
client: "CesiumJS",
},
});
Expand Down
80 changes: 37 additions & 43 deletions packages/engine/Source/Scene/ITwinData.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import defined from "../Core/defined.js";
import Resource from "../Core/Resource.js";
import ITwinPlatform from "../Core/ITwinPlatform.js";
import RuntimeError from "../Core/RuntimeError.js";
import Check from "../Core/Check.js";

/**
* Methods for loading iTwin platform data into CesiumJS
Expand All @@ -16,27 +15,51 @@ import Check from "../Core/Check.js";
const ITwinData = {};

/**
* @param {ExportRepresentation} exportObj
* @param {Cesium3DTileset.ConstructorOptions} [options] Object containing options to pass to an internally created {@link Cesium3DTileset}.
* @returns {Promise<Cesium3DTileset>}
* Create a {@link Cesium3DTileset} for the given iModel id using the mesh export service.
*
* If there is not a completed export available for the given iModel id this function will return <code>undefined</code>.
* We recommend waiting 10-20 seconds and trying to load the tileset again.
* If all exports are Invalid this will throw an error. In that case there's likely something wrong with the iModel itself
*
* @example
* const tileset = await Cesium.ITwinData.createTilesetFromIModelId(iModelId);
* if (Cesium.defined(tileset)) {
* viewer.scene.primitives.add(tileset);
* }
*
* @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
*
* @param {string} iModelId The id of the iModel to load
* @param {Cesium3DTileset.ConstructorOptions} [options] Object containing options to pass to the internally created {@link Cesium3DTileset}.
* @returns {Promise<Cesium3DTileset | undefined>} Will return <code>undefined</code> if there is no completed export for the given iModel id
*
* @throws {RuntimeError} If all exports for the given iModel are Invalid
* @throws {RuntimeError} If the iTwin API request is not successful
*/
async function loadExport(exportObj, options) {
//>>includeStart('debug', pragmas.debug);
Check.defined("exportObj", exportObj);
//>>includeEnd('debug')
ITwinData.createTilesetFromIModelId = async function (iModelId, options) {
const { exports } = await ITwinPlatform.getExports(iModelId);

if (exportObj.request.exportType !== ITwinPlatform.ExportType["3DTILES"]) {
throw new RuntimeError(`Wrong export type ${exportObj.request.exportType}`);
}
if (exportObj.status !== ITwinPlatform.ExportStatus.Complete) {
if (
exports.every((exportObj) => {
return exportObj.status === ITwinPlatform.ExportStatus.Invalid;
})
) {
throw new RuntimeError(
`Export is not completed. ${exportObj.id} - ${exportObj.status}`,
`All exports for this iModel are Invalid: ${iModelId}`,
);
}

const completeExport = exports.find((exportObj) => {
return exportObj.status === ITwinPlatform.ExportStatus.Complete;
});

if (!defined(completeExport)) {
return;
}

// Convert the link to the tileset url while preserving the search paramaters
// This link is only valid 1 hour
const baseUrl = new URL(exportObj._links.mesh.href);
const baseUrl = new URL(completeExport._links.mesh.href);
baseUrl.pathname = `${baseUrl.pathname}/tileset.json`;
const tilesetUrl = baseUrl.toString();

Expand All @@ -45,35 +68,6 @@ async function loadExport(exportObj, options) {
});

return Cesium3DTileset.fromUrl(resource, options);
}

/**
* Loads the export for the specified iModel with the export type that CesiumJS can load and returns
* a tileset created from that export.
*
* If the export is not finished processing this will throw an error. It is up to the caller
* to re-attempt loading at a later time
*
* @example
* const tileset = await Cesium.ITwinData.createTilesetFromIModelId(iModelId);
* viewer.scene.primitives.add(tileset);
*
* @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
*
* @param {string} iModelId The id of the iModel to load
* @param {Cesium3DTileset.ConstructorOptions} [options] Object containing options to pass to an internally created {@link Cesium3DTileset}.
* @returns {Promise<Cesium3DTileset | undefined>} Will return <code>undefined</code> if there is no export for the given iModel id
*
* @throws {RuntimeError} Wrong export type [type]
* @throws {RuntimeError} Export is not completed. [id] - [status]
*/
ITwinData.createTilesetFromIModelId = async function (iModelId, options) {
const { exports } = await ITwinPlatform.getExports(iModelId);
const cesiumExport = exports[0];
if (!defined(cesiumExport)) {
return;
}
return loadExport(cesiumExport, options);
};

export default ITwinData;

0 comments on commit 47e1642

Please sign in to comment.