@itwin/core-backend
Version:
iTwin.js backend components
78 lines • 4.04 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { CompressedId64Set, Logger, StopWatch } from "@itwin/core-bentley";
import { Range3d } from "@itwin/core-geometry";
import { BackendLoggerCategory } from "./BackendLoggerCategory";
const loggerCategory = BackendLoggerCategory.CustomViewState3dCreator;
/**
* Class which helps to generate a custom ViewState3d.
* @internal
*/
export class CustomViewState3dCreator {
_imodel;
constructor(iModel) {
this._imodel = iModel;
}
/** Gets default view state data such as category Ids and modelextents. If no model ids are passed in, all 3D models in the iModel are used.
* @param [modelIds] Ids of models to display in the view.
* @throws [IModelError]($common) If no 3d models are found in the iModel.
*/
async getCustomViewState3dData(options) {
let decompressedModelIds;
if (options?.modelIds !== undefined)
decompressedModelIds = CompressedId64Set.decompressArray(options.modelIds);
const models = decompressedModelIds ?? await this._getAllModels();
const categories = await this._getAllCategories();
const modelExtents = await this._getModelExtents(models);
return {
modelIds: CompressedId64Set.sortAndCompress(models),
categoryIds: CompressedId64Set.sortAndCompress(categories),
modelExtents: modelExtents.toJSON(),
};
}
async _getAllCategories() {
// Only use categories with elements in them
Logger.logInfo(loggerCategory, "Starting getAllCategories query.");
const query = `SELECT DISTINCT Category.Id AS id FROM BisCore.GeometricElement3d WHERE Category.Id IN (SELECT ECInstanceId FROM BisCore.SpatialCategory)`;
const categories = await this._executeQuery(query);
Logger.logInfo(loggerCategory, "Finished getAllCategories query.");
return categories;
}
/** Compute the union of the extents of all the specified models. */
async _getModelExtents(modelIds) {
if (modelIds.length === 0)
return new Range3d();
const timer = new StopWatch("getModelExtents query", true);
const range = await this._imodel.models.queryRange(modelIds);
timer.stop();
Logger.logInfo(loggerCategory, "Finished getModelExtents query.", { timeElapsedMs: timer.elapsed });
return range;
}
/** Get the Ids of all spatially-located, non-template 3d models in the iModel. */
async _getAllModels() {
// Note: IsNotSpatiallyLocated was introduced in a later version of the BisCore ECSchema.
// If the iModel has an earlier version, the statement will throw because the property does not exist.
// If the iModel was created from an earlier version and later upgraded to a newer version, the property may be NULL for models created prior to the upgrade.
const select = "SELECT ECInstanceId FROM Bis.GeometricModel3D WHERE IsPrivate = false AND IsTemplate = false";
const spatialCriterion = "AND (IsNotSpatiallyLocated IS NULL OR IsNotSpatiallyLocated = false)";
let models = [];
Logger.logInfo(loggerCategory, "Starting getAllModels query.");
try {
models = await this._executeQuery(`${select} ${spatialCriterion}`);
}
catch {
models = await this._executeQuery(select);
}
Logger.logInfo(loggerCategory, "Finished getAllModels query.");
return models;
}
_executeQuery = async (query) => {
const rows = [];
for await (const row of this._imodel.createQueryReader(query))
rows.push(row.id);
return rows;
};
}
//# sourceMappingURL=CustomViewState3dCreator.js.map