@itwin/core-frontend 4.1.0-dev.6 → 4.1.0-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/lib/cjs/core-frontend.d.ts +3 -0
  2. package/lib/cjs/core-frontend.d.ts.map +1 -1
  3. package/lib/cjs/core-frontend.js +3 -0
  4. package/lib/cjs/core-frontend.js.map +1 -1
  5. package/lib/cjs/imdl/ImdlGraphicsCreator.d.ts +19 -0
  6. package/lib/cjs/imdl/ImdlGraphicsCreator.d.ts.map +1 -0
  7. package/lib/cjs/imdl/ImdlGraphicsCreator.js +328 -0
  8. package/lib/cjs/imdl/ImdlGraphicsCreator.js.map +1 -0
  9. package/lib/cjs/imdl/ImdlModel.d.ts +181 -0
  10. package/lib/cjs/imdl/ImdlModel.d.ts.map +1 -0
  11. package/lib/cjs/imdl/ImdlModel.js +10 -0
  12. package/lib/cjs/imdl/ImdlModel.js.map +1 -0
  13. package/lib/cjs/imdl/ImdlParser.d.ts +40 -0
  14. package/lib/cjs/imdl/ImdlParser.d.ts.map +1 -0
  15. package/lib/cjs/imdl/ImdlParser.js +996 -0
  16. package/lib/cjs/imdl/ImdlParser.js.map +1 -0
  17. package/lib/cjs/imdl/ImdlSchema.d.ts +380 -0
  18. package/lib/cjs/imdl/ImdlSchema.d.ts.map +1 -0
  19. package/lib/cjs/imdl/ImdlSchema.js +10 -0
  20. package/lib/cjs/imdl/ImdlSchema.js.map +1 -0
  21. package/lib/cjs/render/primitives/AuxChannelTable.d.ts +4 -0
  22. package/lib/cjs/render/primitives/AuxChannelTable.d.ts.map +1 -1
  23. package/lib/cjs/render/primitives/AuxChannelTable.js +33 -0
  24. package/lib/cjs/render/primitives/AuxChannelTable.js.map +1 -1
  25. package/lib/cjs/render/primitives/VertexTable.d.ts +3 -3
  26. package/lib/cjs/render/primitives/VertexTable.d.ts.map +1 -1
  27. package/lib/cjs/render/primitives/VertexTable.js.map +1 -1
  28. package/lib/cjs/render/primitives/VertexTableSplitter.d.ts +5 -1
  29. package/lib/cjs/render/primitives/VertexTableSplitter.d.ts.map +1 -1
  30. package/lib/cjs/render/primitives/VertexTableSplitter.js +13 -12
  31. package/lib/cjs/render/primitives/VertexTableSplitter.js.map +1 -1
  32. package/lib/cjs/tile/IModelTile.d.ts.map +1 -1
  33. package/lib/cjs/tile/IModelTile.js +14 -15
  34. package/lib/cjs/tile/IModelTile.js.map +1 -1
  35. package/lib/cjs/tile/ImdlReader.d.ts +11 -420
  36. package/lib/cjs/tile/ImdlReader.d.ts.map +1 -1
  37. package/lib/cjs/tile/ImdlReader.js +64 -902
  38. package/lib/cjs/tile/ImdlReader.js.map +1 -1
  39. package/lib/cjs/tile/map/MapTile.d.ts +6 -1
  40. package/lib/cjs/tile/map/MapTile.d.ts.map +1 -1
  41. package/lib/cjs/tile/map/MapTile.js +8 -7
  42. package/lib/cjs/tile/map/MapTile.js.map +1 -1
  43. package/lib/cjs/tile/map/MapTileTree.d.ts.map +1 -1
  44. package/lib/cjs/tile/map/MapTileTree.js +8 -2
  45. package/lib/cjs/tile/map/MapTileTree.js.map +1 -1
  46. package/lib/esm/core-frontend.d.ts +3 -0
  47. package/lib/esm/core-frontend.d.ts.map +1 -1
  48. package/lib/esm/core-frontend.js +3 -0
  49. package/lib/esm/core-frontend.js.map +1 -1
  50. package/lib/esm/imdl/ImdlGraphicsCreator.d.ts +19 -0
  51. package/lib/esm/imdl/ImdlGraphicsCreator.d.ts.map +1 -0
  52. package/lib/esm/imdl/ImdlGraphicsCreator.js +324 -0
  53. package/lib/esm/imdl/ImdlGraphicsCreator.js.map +1 -0
  54. package/lib/esm/imdl/ImdlModel.d.ts +181 -0
  55. package/lib/esm/imdl/ImdlModel.d.ts.map +1 -0
  56. package/lib/esm/imdl/ImdlModel.js +9 -0
  57. package/lib/esm/imdl/ImdlModel.js.map +1 -0
  58. package/lib/esm/imdl/ImdlParser.d.ts +40 -0
  59. package/lib/esm/imdl/ImdlParser.d.ts.map +1 -0
  60. package/lib/esm/imdl/ImdlParser.js +988 -0
  61. package/lib/esm/imdl/ImdlParser.js.map +1 -0
  62. package/lib/esm/imdl/ImdlSchema.d.ts +380 -0
  63. package/lib/esm/imdl/ImdlSchema.d.ts.map +1 -0
  64. package/lib/esm/imdl/ImdlSchema.js +9 -0
  65. package/lib/esm/imdl/ImdlSchema.js.map +1 -0
  66. package/lib/esm/render/primitives/AuxChannelTable.d.ts +4 -0
  67. package/lib/esm/render/primitives/AuxChannelTable.d.ts.map +1 -1
  68. package/lib/esm/render/primitives/AuxChannelTable.js +33 -0
  69. package/lib/esm/render/primitives/AuxChannelTable.js.map +1 -1
  70. package/lib/esm/render/primitives/VertexTable.d.ts +3 -3
  71. package/lib/esm/render/primitives/VertexTable.d.ts.map +1 -1
  72. package/lib/esm/render/primitives/VertexTable.js.map +1 -1
  73. package/lib/esm/render/primitives/VertexTableSplitter.d.ts +5 -1
  74. package/lib/esm/render/primitives/VertexTableSplitter.d.ts.map +1 -1
  75. package/lib/esm/render/primitives/VertexTableSplitter.js +13 -12
  76. package/lib/esm/render/primitives/VertexTableSplitter.js.map +1 -1
  77. package/lib/esm/tile/IModelTile.d.ts.map +1 -1
  78. package/lib/esm/tile/IModelTile.js +14 -15
  79. package/lib/esm/tile/IModelTile.js.map +1 -1
  80. package/lib/esm/tile/ImdlReader.d.ts +11 -420
  81. package/lib/esm/tile/ImdlReader.d.ts.map +1 -1
  82. package/lib/esm/tile/ImdlReader.js +67 -903
  83. package/lib/esm/tile/ImdlReader.js.map +1 -1
  84. package/lib/esm/tile/map/MapTile.d.ts +6 -1
  85. package/lib/esm/tile/map/MapTile.d.ts.map +1 -1
  86. package/lib/esm/tile/map/MapTile.js +8 -7
  87. package/lib/esm/tile/map/MapTile.js.map +1 -1
  88. package/lib/esm/tile/map/MapTileTree.d.ts.map +1 -1
  89. package/lib/esm/tile/map/MapTileTree.js +8 -2
  90. package/lib/esm/tile/map/MapTileTree.js.map +1 -1
  91. package/package.json +18 -18
@@ -5,62 +5,13 @@
5
5
  /** @packageDocumentation
6
6
  * @module Tiles
7
7
  */
8
- import { assert, ByteStream, JsonUtils, utf8ToString } from "@itwin/core-bentley";
9
- import { ClipVector, Point2d, Point3d, Range2d, Range3d, Transform } from "@itwin/core-geometry";
10
- import { BatchType, ColorDef, decodeTileContentDescription, FeatureTableHeader, FillFlags, GltfV2ChunkTypes, GltfVersions, Gradient, ImageSource, ImdlFlags, ImdlHeader, LinePixels, MultiModelPackedFeatureTable, PackedFeatureTable, PolylineTypeFlags, QParams2d, QParams3d, RenderMaterial, RenderTexture, TextureMapping, TileFormat, TileHeader, TileReadError, TileReadStatus, } from "@itwin/core-common";
8
+ import { ByteStream } from "@itwin/core-bentley";
9
+ import { Point3d, Transform } from "@itwin/core-geometry";
10
+ import { BatchType, decodeTileContentDescription, TileReadError, TileReadStatus, } from "@itwin/core-common";
11
11
  import { IModelApp } from "../IModelApp";
12
- import { AnimationNodeId, GraphicBranch } from "../render/GraphicBranch";
13
- import { AuxChannelTable } from "../render/primitives/AuxChannelTable";
14
- import { DisplayParams } from "../render/primitives/DisplayParams";
15
- import { Mesh } from "../render/primitives/mesh/MeshPrimitives";
16
- import { createSurfaceMaterial, isValidSurfaceType, SurfaceType } from "../render/primitives/SurfaceParams";
17
- import { MeshParams, VertexIndices, VertexTable } from "../render/primitives/VertexTable";
18
- import { splitMeshParams, splitPointStringParams, splitPolylineParams } from "../render/primitives/VertexTableSplitter";
19
- import { PointStringParams } from "../render/primitives/PointStringParams";
20
- import { PolylineParams } from "../render/primitives/PolylineParams";
21
- /** Header preceding "glTF" data in iMdl tile.
22
- * @internal
23
- */
24
- export class GltfHeader extends TileHeader {
25
- get isValid() { return TileFormat.Gltf === this.format; }
26
- constructor(stream) {
27
- super(stream);
28
- this.scenePosition = 0;
29
- this.sceneStrLength = 0;
30
- this.binaryPosition = 0;
31
- this.gltfLength = stream.readUint32();
32
- this.sceneStrLength = stream.readUint32();
33
- const value5 = stream.readUint32();
34
- // Early versions of the reality data tile publisher incorrectly put version 2 into header - handle these old tiles
35
- // validating the chunk type.
36
- if (this.version === GltfVersions.Version2 && value5 === GltfVersions.Gltf1SceneFormat)
37
- this.version = GltfVersions.Version1;
38
- if (this.version === GltfVersions.Version1) {
39
- const gltfSceneFormat = value5;
40
- if (GltfVersions.Gltf1SceneFormat !== gltfSceneFormat) {
41
- this.invalidate();
42
- return;
43
- }
44
- this.scenePosition = stream.curPos;
45
- this.binaryPosition = stream.curPos + this.sceneStrLength;
46
- }
47
- else if (this.version === GltfVersions.Version2) {
48
- const sceneChunkType = value5;
49
- this.scenePosition = stream.curPos;
50
- stream.curPos = stream.curPos + this.sceneStrLength;
51
- const binaryLength = stream.readUint32();
52
- const binaryChunkType = stream.readUint32();
53
- if (GltfV2ChunkTypes.JSON !== sceneChunkType || GltfV2ChunkTypes.Binary !== binaryChunkType || 0 === binaryLength) {
54
- this.invalidate();
55
- return;
56
- }
57
- this.binaryPosition = stream.curPos;
58
- }
59
- else {
60
- this.invalidate();
61
- }
62
- }
63
- }
12
+ import { GraphicBranch } from "../render/GraphicBranch";
13
+ import { convertFeatureTable, parseImdlDocument } from "../imdl/ImdlParser";
14
+ import { decodeImdlGraphics } from "../imdl/ImdlGraphicsCreator";
64
15
  /** Convert the byte array returned by [[TileAdmin.requestElementGraphics]] into a [[RenderGraphic]].
65
16
  * @param bytes The binary graphics data obtained from `requestElementGraphics`.
66
17
  * @param iModel The iModel with which the graphics are associated.
@@ -76,860 +27,73 @@ export async function readElementGraphics(bytes, iModel, modelId, is3d, options)
76
27
  stream, iModel, modelId, is3d, options,
77
28
  system: IModelApp.renderSystem,
78
29
  });
79
- if (!reader)
80
- return undefined;
81
30
  const result = await reader.read();
82
31
  return result.graphic;
83
32
  }
84
- const nodeIdRegex = /Node_(.*)/;
85
- function extractNodeId(nodeName) {
86
- const match = nodeName.match(nodeIdRegex);
87
- assert(!!match && match.length === 2);
88
- if (!match || match.length !== 2)
89
- return 0;
90
- const nodeId = Number.parseInt(match[1], 10);
91
- assert(!Number.isNaN(nodeId));
92
- return Number.isNaN(nodeId) ? 0 : nodeId;
93
- }
94
- /** Deserializes tile content in iMdl format. These tiles contain element geometry encoded into a format optimized for the imodeljs webgl renderer.
95
- * @internal
96
- */
97
- export class ImdlReader {
98
- get _isCanceled() { return undefined !== this._canceled && this._canceled(this); }
99
- get _isVolumeClassifier() { return BatchType.VolumeClassifier === this._type; }
100
- /** Attempt to initialize an ImdlReader to deserialize iModel tile data beginning at the stream's current position. */
101
- static create(args) {
102
- const imdlHeader = new ImdlHeader(args.stream);
103
- if (!imdlHeader.isValid || !imdlHeader.isReadableVersion)
104
- return undefined;
105
- // The feature table follows the iMdl header
106
- if (!this.skipFeatureTable(args.stream))
107
- return undefined;
108
- // A glTF header follows the feature table
109
- const gltfHeader = new GltfHeader(args.stream);
110
- if (!gltfHeader.isValid)
111
- return undefined;
112
- args.stream.curPos = gltfHeader.scenePosition;
113
- const sceneStrData = args.stream.nextBytes(gltfHeader.sceneStrLength);
114
- const sceneStr = utf8ToString(sceneStrData);
115
- if (!sceneStr)
116
- return undefined;
117
- try {
118
- const sceneValue = JSON.parse(sceneStr);
119
- const imdl = {
120
- scene: JsonUtils.asString(sceneValue.scene),
121
- scenes: JsonUtils.asArray(sceneValue.scenes),
122
- animationNodes: JsonUtils.asObject(sceneValue.animationNodes),
123
- bufferViews: JsonUtils.asObject(sceneValue.bufferViews),
124
- meshes: JsonUtils.asObject(sceneValue.meshes),
125
- nodes: JsonUtils.asObject(sceneValue.nodes),
126
- materials: JsonUtils.asObject(sceneValue.materials),
127
- renderMaterials: JsonUtils.asObject(sceneValue.renderMaterials),
128
- namedTextures: JsonUtils.asObject(sceneValue.namedTextures),
129
- patternSymbols: JsonUtils.asObject(sceneValue.patternSymbols),
130
- rtcCenter: JsonUtils.asArray(sceneValue.rtcCenter),
131
- };
132
- return undefined !== imdl.meshes ? new ImdlReader(imdl, gltfHeader.binaryPosition, args, 0 !== (imdlHeader.flags & ImdlFlags.MultiModelFeatureTable)) : undefined;
133
- }
134
- catch (_) {
135
- return undefined;
136
- }
137
- }
138
- constructor(imdl, binaryPosition, args, hasMultiModelFeatureTable) {
139
- this._patternGeometry = new Map();
140
- this._buffer = args.stream;
141
- this._binaryData = new Uint8Array(this._buffer.arrayBuffer, binaryPosition);
142
- this._hasMultiModelFeatureTable = hasMultiModelFeatureTable;
143
- this._animationNodes = JsonUtils.asObject(imdl.animationNodes);
144
- this._bufferViews = imdl.bufferViews;
145
- this._meshes = imdl.meshes;
146
- this._nodes = imdl.nodes;
147
- this._materialValues = imdl.materials ?? {};
148
- this._renderMaterials = imdl.renderMaterials ?? {};
149
- this._namedTextures = imdl.namedTextures ?? {};
150
- this._patternSymbols = imdl.patternSymbols ?? {};
151
- this._rtcCenter = imdl.rtcCenter ? Point3d.fromJSON(imdl.rtcCenter) : undefined;
152
- this._iModel = args.iModel;
153
- this._modelId = args.modelId;
154
- this._is3d = args.is3d;
155
- this._isLeaf = args.isLeaf;
156
- this._system = args.system;
157
- this._type = args.type ?? BatchType.Primary;
158
- this._canceled = args.isCanceled;
159
- this._sizeMultiplier = args.sizeMultiplier;
160
- this._loadEdges = args.loadEdges ?? true;
161
- this._options = args.options ?? {};
162
- this._containsTransformNodes = args.containsTransformNodes ?? false;
163
- this._timeline = args.timeline;
164
- }
165
- /** Attempt to deserialize the tile data */
166
- async read() {
167
- let content;
168
- try {
169
- content = decodeTileContentDescription({
170
- stream: this._buffer,
171
- sizeMultiplier: this._sizeMultiplier,
172
- is2d: !this._is3d,
173
- options: IModelApp.tileAdmin,
174
- isVolumeClassifier: this._isVolumeClassifier,
175
- isLeaf: this._isLeaf,
176
- });
177
- }
178
- catch (e) {
179
- if (e instanceof TileReadError)
180
- return { isLeaf: true, readStatus: e.errorNumber };
181
- else
182
- throw e;
183
- }
184
- const featureTable = this.readFeatureTable(content.featureTableStartPos);
185
- if (undefined === featureTable)
186
- return { readStatus: TileReadStatus.InvalidFeatureTable, isLeaf: true };
187
- // Textures must be loaded asynchronously first...
188
- await this.loadNamedTextures();
189
- if (this._isCanceled)
190
- return { readStatus: TileReadStatus.Canceled, isLeaf: true };
191
- return this.finishRead(content.isLeaf, featureTable, content.contentRange, content.emptySubRangeMask, content.sizeMultiplier);
192
- }
193
- /** @internal */
194
- createDisplayParams(json) {
195
- const type = JsonUtils.asInt(json.type, DisplayParams.Type.Mesh);
196
- const lineColor = ColorDef.create(JsonUtils.asInt(json.lineColor));
197
- const fillColor = ColorDef.create(JsonUtils.asInt(json.fillColor));
198
- const width = JsonUtils.asInt(json.lineWidth);
199
- const linePixels = JsonUtils.asInt(json.linePixels, LinePixels.Solid);
200
- const fillFlags = JsonUtils.asInt(json.fillFlags, FillFlags.None);
201
- const ignoreLighting = JsonUtils.asBool(json.ignoreLighting);
202
- // Material will always contain its own texture if it has one
203
- const materialKey = json.materialId;
204
- const material = undefined !== materialKey ? this.materialFromJson(materialKey) : undefined;
205
- // We will only attempt to include the texture if material is undefined
206
- let textureMapping;
207
- if (!material) {
208
- const textureJson = json.texture;
209
- textureMapping = undefined !== textureJson ? this.textureMappingFromJson(textureJson) : undefined;
210
- if (undefined === textureMapping) {
211
- // Look for a gradient. If defined, create a texture mapping. No reason to pass the Gradient.Symb to the DisplayParams once we have the texture.
212
- const gradientProps = json.gradient;
213
- const gradient = undefined !== gradientProps ? Gradient.Symb.fromJSON(gradientProps) : undefined;
214
- if (undefined !== gradient) {
215
- const texture = this._system.getGradientTexture(gradient, this._iModel);
216
- if (undefined !== texture) {
217
- // ###TODO: would be better if DisplayParams created the TextureMapping - but that requires an IModelConnection and a RenderSystem...
218
- textureMapping = new TextureMapping(texture, new TextureMapping.Params({ textureMat2x3: new TextureMapping.Trans2x3(0, 1, 0, 1, 0, 0) }));
219
- }
220
- }
221
- }
222
- }
223
- return new DisplayParams(type, lineColor, fillColor, width, linePixels, fillFlags, material, undefined, ignoreLighting, textureMapping);
224
- }
225
- /** @internal */
226
- colorDefFromMaterialJson(json) {
227
- return undefined !== json ? ColorDef.from(json[0] * 255 + 0.5, json[1] * 255 + 0.5, json[2] * 255 + 0.5) : undefined;
228
- }
229
- /** @internal */
230
- materialFromJson(key) {
231
- const material = this._system.findMaterial(key, this._iModel);
232
- if (material)
233
- return material;
234
- if (!this._renderMaterials)
235
- return undefined;
236
- const materialJson = this._renderMaterials[key];
237
- if (!materialJson)
238
- return undefined;
239
- // eslint-disable-next-line deprecation/deprecation
240
- const materialParams = new RenderMaterial.Params(key);
241
- materialParams.diffuseColor = this.colorDefFromMaterialJson(materialJson.diffuseColor);
242
- if (materialJson.diffuse !== undefined)
243
- materialParams.diffuse = JsonUtils.asDouble(materialJson.diffuse);
244
- materialParams.specularColor = this.colorDefFromMaterialJson(materialJson.specularColor);
245
- if (materialJson.specular !== undefined)
246
- materialParams.specular = JsonUtils.asDouble(materialJson.specular);
247
- materialParams.reflectColor = this.colorDefFromMaterialJson(materialJson.reflectColor);
248
- if (materialJson.reflect !== undefined)
249
- materialParams.reflect = JsonUtils.asDouble(materialJson.reflect);
250
- if (materialJson.specularExponent !== undefined)
251
- materialParams.specularExponent = materialJson.specularExponent;
252
- if (undefined !== materialJson.transparency)
253
- materialParams.alpha = 1.0 - materialJson.transparency;
254
- materialParams.refract = JsonUtils.asDouble(materialJson.refract);
255
- materialParams.shadows = JsonUtils.asBool(materialJson.shadows);
256
- materialParams.ambient = JsonUtils.asDouble(materialJson.ambient);
257
- if (undefined !== materialJson.textureMapping)
258
- materialParams.textureMapping = this.textureMappingFromJson(materialJson.textureMapping.texture);
259
- // eslint-disable-next-line deprecation/deprecation
260
- return this._system.createMaterial(materialParams, this._iModel);
261
- }
262
- constantLodParamPropsFromJson(propsJson) {
263
- if (undefined === propsJson)
264
- return undefined;
265
- const constantLodPops = {
266
- repetitions: JsonUtils.asDouble(propsJson.repetitions, 1.0),
267
- offset: { x: propsJson.offset ? JsonUtils.asDouble(propsJson.offset[0]) : 0.0, y: propsJson.offset ? JsonUtils.asDouble(propsJson.offset[1]) : 0.0 },
268
- minDistClamp: JsonUtils.asDouble(propsJson.minDistClamp, 1.0),
269
- maxDistClamp: JsonUtils.asDouble(propsJson.maxDistClamp, 4096.0 * 1024.0 * 1024.0),
270
- };
271
- return constantLodPops;
272
- }
273
- textureMappingFromJson(json) {
274
- if (undefined === json)
275
- return undefined;
276
- const name = JsonUtils.asString(json.name);
277
- const namedTex = 0 !== name.length ? this._namedTextures[name] : undefined;
278
- const texture = undefined !== namedTex ? namedTex.renderTexture : undefined;
279
- if (undefined === texture) {
280
- assert(false, "bad texture mapping json");
281
- return undefined;
282
- }
283
- const paramsJson = json.params;
284
- const tf = paramsJson.transform;
285
- const paramProps = {
286
- textureMat2x3: new TextureMapping.Trans2x3(tf[0][0], tf[0][1], tf[0][2], tf[1][0], tf[1][1], tf[1][2]),
287
- textureWeight: JsonUtils.asDouble(paramsJson.weight, 1.0),
288
- mapMode: JsonUtils.asInt(paramsJson.mode),
289
- worldMapping: JsonUtils.asBool(paramsJson.worldMapping),
290
- useConstantLod: JsonUtils.asBool(paramsJson.useConstantLod),
291
- constantLodProps: this.constantLodParamPropsFromJson(paramsJson.constantLodParams),
292
- };
293
- const textureMapping = new TextureMapping(texture, new TextureMapping.Params(paramProps));
294
- const normalMapJson = json.normalMapParams;
295
- if (normalMapJson) {
296
- let normalMap;
297
- const normalTexName = JsonUtils.asString(normalMapJson.textureName);
298
- if (normalTexName.length === 0 || undefined !== (normalMap = this._namedTextures[normalTexName]?.renderTexture)) {
299
- textureMapping.normalMapParams = {
300
- normalMap,
301
- greenUp: JsonUtils.asBool(normalMapJson.greenUp),
302
- scale: JsonUtils.asDouble(normalMapJson.scale, 1),
303
- useConstantLod: JsonUtils.asBool(normalMapJson.useConstantLod),
304
- };
305
- }
306
- }
307
- return textureMapping;
308
- }
309
- async loadNamedTextures() {
310
- if (undefined === this._namedTextures)
311
- return;
312
- const promises = new Array();
313
- for (const name of Object.keys(this._namedTextures))
314
- promises.push(this.loadNamedTexture(name));
315
- if (promises.length > 0)
316
- await Promise.all(promises);
317
- }
318
- async loadNamedTexture(name) {
319
- if (this._isCanceled)
320
- return;
321
- const namedTex = this._namedTextures[name];
322
- assert(undefined !== namedTex); // we got here by iterating the keys of this.namedTextures...
323
- if (undefined === namedTex)
324
- return;
325
- const texture = this._system.findTexture(name, this._iModel);
326
- if (undefined !== texture) {
327
- namedTex.renderTexture = texture;
328
- return;
329
- }
330
- namedTex.renderTexture = await this.readNamedTexture(namedTex, name);
331
- }
332
- async readNamedTexture(namedTex, name) {
333
- // Reasons a texture could be embedded in the tile content instead of requested separately from the backend:
334
- // - external textures are disabled
335
- // - the texture name is not a valid Id64 string
336
- // - the texture is below a certain backend-hardcoded size threshold
337
- // The bufferViewJson being defined signifies any of the above conditions. In that case, the image content
338
- // has been embedded in the tile contents. Otherwise, we will attempt to request the image content separately
339
- // from the backend.
340
- let textureType = RenderTexture.Type.Normal;
341
- const isGlyph = JsonUtils.asBool(namedTex.isGlyph);
342
- const isTileSection = !isGlyph && JsonUtils.asBool(namedTex.isTileSection);
343
- if (isGlyph)
344
- textureType = RenderTexture.Type.Glyph;
345
- else if (isTileSection)
346
- textureType = RenderTexture.Type.TileSection;
347
- // We produce unique tile sections for very large (> 8 megapixel) textures, and unique glyph atlases for raster text.
348
- // Neither should be cached.
349
- const cacheable = !isGlyph && !isTileSection;
350
- const ownership = cacheable ? { iModel: this._iModel, key: name } : undefined;
351
- const bufferViewId = JsonUtils.asString(namedTex.bufferView);
352
- const bufferViewJson = 0 !== bufferViewId.length ? this._bufferViews[bufferViewId] : undefined;
353
- if (undefined !== bufferViewJson) { // presence of bufferViewJson signifies we should read the texture from the tile content
354
- const byteOffset = JsonUtils.asInt(bufferViewJson.byteOffset);
355
- const byteLength = JsonUtils.asInt(bufferViewJson.byteLength);
356
- if (0 === byteLength)
357
- return undefined;
358
- const texBytes = this._binaryData.subarray(byteOffset, byteOffset + byteLength);
359
- const format = namedTex.format;
360
- const source = new ImageSource(texBytes, format);
361
- return this._system.createTextureFromSource({ source, ownership, type: textureType, transparency: namedTex.transparency });
362
- }
363
- // bufferViewJson was undefined, so attempt to request the texture directly from the backend
364
- // eslint-disable-next-line deprecation/deprecation
365
- const params = new RenderTexture.Params(cacheable ? name : undefined, textureType);
366
- return this._system.createTextureFromElement(name, this._iModel, params, namedTex.format);
367
- }
368
- /** @internal */
369
- readFeatureTable(startPos) {
370
- this._buffer.curPos = startPos;
371
- const header = FeatureTableHeader.readFrom(this._buffer);
372
- if (undefined === header || 0 !== header.length % 4)
373
- return undefined;
374
- // NB: We make a copy of the sub-array because we don't want to pin the entire data array in memory.
375
- const numUint32s = (header.length - FeatureTableHeader.sizeInBytes) / 4;
376
- const packedFeatureArray = new Uint32Array(this._buffer.nextUint32s(numUint32s));
377
- if (this._buffer.isPastTheEnd)
378
- return undefined;
379
- let featureTable;
380
- if (this._hasMultiModelFeatureTable) {
381
- featureTable = MultiModelPackedFeatureTable.create(packedFeatureArray, this._modelId, header.count, this._type, header.numSubCategories);
382
- }
383
- else {
384
- let animNodesArray;
385
- const animationNodes = this._animationNodes;
386
- if (undefined !== animationNodes) {
387
- const bytesPerId = JsonUtils.asInt(animationNodes.bytesPerId);
388
- const bufferViewId = JsonUtils.asString(animationNodes.bufferView);
389
- const bufferViewJson = this._bufferViews[bufferViewId];
390
- if (undefined !== bufferViewJson) {
391
- const byteOffset = JsonUtils.asInt(bufferViewJson.byteOffset);
392
- const byteLength = JsonUtils.asInt(bufferViewJson.byteLength);
393
- const bytes = this._binaryData.subarray(byteOffset, byteOffset + byteLength);
394
- switch (bytesPerId) {
395
- case 1:
396
- animNodesArray = new Uint8Array(bytes);
397
- break;
398
- case 2:
399
- // NB: A *copy* of the subarray.
400
- animNodesArray = Uint16Array.from(new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2));
401
- break;
402
- case 4:
403
- // NB: A *copy* of the subarray.
404
- animNodesArray = Uint32Array.from(new Uint32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4));
405
- break;
406
- }
407
- }
408
- }
409
- featureTable = new PackedFeatureTable(packedFeatureArray, this._modelId, header.count, this._type, animNodesArray);
410
- }
411
- this._buffer.curPos = startPos + header.length;
412
- return featureTable;
413
- }
414
- static skipFeatureTable(stream) {
415
- const startPos = stream.curPos;
416
- const header = FeatureTableHeader.readFrom(stream);
417
- if (undefined !== header)
418
- stream.curPos = startPos + header.length;
419
- return undefined !== header;
420
- }
421
- readAreaPattern(json) {
422
- const geometry = this.getPatternGeometry(json.symbolName);
423
- if (!geometry || geometry.length === 0)
424
- return undefined;
425
- const xyOffsets = this.findBuffer(json.xyOffsets);
426
- if (!xyOffsets)
427
- return undefined;
428
- const clip = ClipVector.fromJSON(json.clip);
429
- const clipVolume = clip && clip.isValid ? this._system.createClipVolume(clip) : undefined;
430
- if (!clipVolume)
431
- return undefined;
432
- const viewIndependentOrigin = json.viewIndependentOrigin ? Point3d.fromJSON(json.viewIndependentOrigin) : undefined;
433
- const pattern = this._system.createAreaPattern({
434
- xyOffsets: new Float32Array(xyOffsets.buffer, xyOffsets.byteOffset, xyOffsets.byteLength / 4),
435
- featureId: json.featureId,
436
- orgTransform: Transform.fromJSON(json.orgTransform),
437
- origin: Point2d.fromJSON(json.origin),
438
- scale: json.scale,
439
- spacing: Point2d.fromJSON(json.spacing),
440
- patternToModel: Transform.fromJSON(json.modelTransform),
441
- range: Range3d.fromJSON(json.range),
442
- symbolTranslation: Point3d.fromJSON(json.symbolTranslation),
443
- viewIndependentOrigin,
33
+ async function readImdlContent(args) {
34
+ let content;
35
+ try {
36
+ content = decodeTileContentDescription({
37
+ stream: args.stream,
38
+ sizeMultiplier: args.sizeMultiplier,
39
+ is2d: !args.is3d,
40
+ options: IModelApp.tileAdmin,
41
+ isVolumeClassifier: BatchType.VolumeClassifier === args.type,
42
+ isLeaf: args.isLeaf,
444
43
  });
445
- if (!pattern)
446
- return undefined;
447
- const branch = new GraphicBranch(true);
448
- for (const geom of geometry) {
449
- const graphic = this._system.createRenderGraphic(geom, pattern);
450
- if (graphic)
451
- branch.add(graphic);
452
- }
453
- if (branch.isEmpty)
454
- return undefined;
455
- return this._system.createGraphicBranch(branch, Transform.createIdentity(), { clipVolume });
456
- }
457
- readMeshGeometry(primitive) {
458
- const geometry = this.readPrimitiveGeometry(primitive);
459
- if (!geometry)
460
- return undefined;
461
- const instances = this.readInstances(primitive);
462
- return { geometry, instances };
463
- }
464
- readMeshGraphic(primitive) {
465
- if (primitive.type === "areaPattern")
466
- return this.readAreaPattern(primitive);
467
- const geom = this.readMeshGeometry(primitive);
468
- return geom ? this._system.createRenderGraphic(geom.geometry, geom.instances) : undefined;
469
- }
470
- findBuffer(bufferViewId) {
471
- if (typeof bufferViewId !== "string" || 0 === bufferViewId.length)
472
- return undefined;
473
- const bufferViewJson = this._bufferViews[bufferViewId];
474
- if (undefined === bufferViewJson)
475
- return undefined;
476
- const byteOffset = JsonUtils.asInt(bufferViewJson.byteOffset);
477
- const byteLength = JsonUtils.asInt(bufferViewJson.byteLength);
478
- if (0 === byteLength)
479
- return undefined;
480
- return this._binaryData.subarray(byteOffset, byteOffset + byteLength);
481
- }
482
- readVertexTable(primitive) {
483
- const json = primitive.vertices;
484
- if (undefined === json)
485
- return undefined;
486
- const bytes = this.findBuffer(JsonUtils.asString(json.bufferView));
487
- if (undefined === bytes)
488
- return undefined;
489
- const uniformFeatureID = undefined !== json.featureID ? JsonUtils.asInt(json.featureID) : undefined;
490
- const rangeMin = JsonUtils.asArray(json.params.decodedMin);
491
- const rangeMax = JsonUtils.asArray(json.params.decodedMax);
492
- if (undefined === rangeMin || undefined === rangeMax)
493
- return undefined;
494
- const qparams = QParams3d.fromRange(Range3d.create(Point3d.create(rangeMin[0], rangeMin[1], rangeMin[2]), Point3d.create(rangeMax[0], rangeMax[1], rangeMax[2])));
495
- const uniformColor = undefined !== json.uniformColor ? ColorDef.fromJSON(json.uniformColor) : undefined;
496
- let uvParams;
497
- if (Mesh.PrimitiveType.Mesh === primitive.type && primitive.surface && primitive.surface.uvParams) {
498
- const uvMin = primitive.surface.uvParams.decodedMin;
499
- const uvMax = primitive.surface.uvParams.decodedMax;
500
- const uvRange = new Range2d(uvMin[0], uvMin[1], uvMax[0], uvMax[1]);
501
- uvParams = QParams2d.fromRange(uvRange);
502
- }
503
- return new VertexTable({
504
- data: bytes,
505
- qparams,
506
- width: json.width,
507
- height: json.height,
508
- hasTranslucency: json.hasTranslucency,
509
- uniformColor,
510
- featureIndexType: json.featureIndexType,
511
- uniformFeatureID,
512
- numVertices: json.count,
513
- numRgbaPerVertex: json.numRgbaPerVertex,
514
- uvParams,
515
- usesUnquantizedPositions: true === json.usesUnquantizedPositions,
516
- });
517
- }
518
- readAuxChannelTable(primitive) {
519
- const json = primitive.auxChannels;
520
- if (undefined === json)
521
- return undefined;
522
- const bytes = this.findBuffer(JsonUtils.asString(json.bufferView));
523
- if (undefined === bytes)
524
- return undefined;
525
- const props = {
526
- data: bytes,
527
- width: json.width,
528
- height: json.height,
529
- count: json.count,
530
- numBytesPerVertex: json.numBytesPerVertex,
531
- displacements: json.displacements,
532
- normals: json.normals,
533
- params: json.params,
534
- };
535
- return AuxChannelTable.fromJSON(props);
536
- }
537
- readInstances(primitive) {
538
- const json = primitive.instances;
539
- if (undefined === json)
540
- return undefined;
541
- const count = JsonUtils.asInt(json.count, 0);
542
- if (count <= 0)
543
- return undefined;
544
- const centerComponents = JsonUtils.asArray(json.transformCenter);
545
- if (undefined === centerComponents || 3 !== centerComponents.length)
546
- return undefined;
547
- const transformCenter = Point3d.create(centerComponents[0], centerComponents[1], centerComponents[2]);
548
- const featureIds = this.findBuffer(JsonUtils.asString(json.featureIds));
549
- if (undefined === featureIds)
550
- return undefined;
551
- const transformBytes = this.findBuffer(JsonUtils.asString(json.transforms));
552
- if (undefined === transformBytes)
553
- return undefined;
554
- // 1 transform = 3 rows of 4 floats = 12 floats per instance
555
- const numFloats = transformBytes.byteLength / 4;
556
- assert(Math.floor(numFloats) === numFloats);
557
- assert(0 === numFloats % 12);
558
- const transforms = new Float32Array(transformBytes.buffer, transformBytes.byteOffset, numFloats);
559
- let symbologyOverrides;
560
- if (undefined !== json.symbologyOverrides)
561
- symbologyOverrides = this.findBuffer(JsonUtils.asString(json.symbologyOverrides));
562
- return { count, transforms, transformCenter, featureIds, symbologyOverrides };
563
- }
564
- readVertexIndices(bufferName) {
565
- const bytes = this.findBuffer(bufferName);
566
- return undefined !== bytes ? new VertexIndices(bytes) : undefined;
567
- }
568
- readTesselatedPolyline(json) {
569
- const indices = this.readVertexIndices(json.indices);
570
- const prevIndices = this.readVertexIndices(json.prevIndices);
571
- const nextIndicesAndParams = this.findBuffer(json.nextIndicesAndParams);
572
- if (!indices || !prevIndices || !nextIndicesAndParams)
573
- return undefined;
574
- return { indices, prevIndices, nextIndicesAndParams };
575
- }
576
- readSurface(mesh, displayParams) {
577
- const surf = mesh.surface;
578
- if (undefined === surf)
579
- return undefined;
580
- const indices = this.readVertexIndices(surf.indices);
581
- if (undefined === indices)
582
- return undefined;
583
- const type = surf.type;
584
- if (!isValidSurfaceType(type))
585
- return undefined;
586
- const texture = undefined !== displayParams.textureMapping ? displayParams.textureMapping.texture : undefined;
587
- let material;
588
- const atlas = mesh.vertices.materialAtlas;
589
- const numColors = mesh.vertices.numColors;
590
- if (undefined !== atlas && undefined !== numColors) {
591
- material = {
592
- isAtlas: true,
593
- hasTranslucency: JsonUtils.asBool(atlas.hasTranslucency),
594
- overridesAlpha: JsonUtils.asBool(atlas.overridesAlpha, false),
595
- vertexTableOffset: JsonUtils.asInt(numColors),
596
- numMaterials: JsonUtils.asInt(atlas.numMaterials),
597
- };
598
- }
599
- else {
600
- material = createSurfaceMaterial(displayParams.material);
601
- }
602
- const textureMapping = undefined !== texture ? { texture, alwaysDisplayed: JsonUtils.asBool(surf.alwaysDisplayTexture) } : undefined;
603
- return {
604
- type,
605
- indices,
606
- fillFlags: displayParams.fillFlags,
607
- hasBakedLighting: false,
608
- material,
609
- textureMapping,
610
- };
611
- }
612
- readSegmentEdges(json) {
613
- const indices = this.readVertexIndices(json.indices);
614
- const endPointAndQuadIndices = this.findBuffer(json.endPointAndQuadIndices);
615
- return undefined !== indices && undefined !== endPointAndQuadIndices ? { indices, endPointAndQuadIndices } : undefined;
616
- }
617
- readSilhouettes(json) {
618
- const segments = this.readSegmentEdges(json);
619
- const normalPairs = this.findBuffer(json.normalPairs);
620
- return undefined !== segments && undefined !== normalPairs ? { normalPairs, indices: segments.indices, endPointAndQuadIndices: segments.endPointAndQuadIndices } : undefined;
621
- }
622
- readIndexedEdges(json) {
623
- const indices = this.readVertexIndices(json.indices);
624
- const edgeTable = this.findBuffer(json.edges);
625
- if (!indices || !edgeTable)
626
- return undefined;
627
- return {
628
- indices,
629
- edges: {
630
- data: edgeTable,
631
- width: json.width,
632
- height: json.height,
633
- silhouettePadding: json.silhouettePadding,
634
- numSegments: json.numSegments,
635
- },
636
- };
637
- }
638
- readEdges(json, displayParams) {
639
- let segments;
640
- let silhouettes;
641
- let polylines;
642
- let indexed;
643
- let succeeded = false;
644
- if (undefined !== json.segments && undefined === (segments = this.readSegmentEdges(json.segments)))
645
- return { succeeded };
646
- if (undefined !== json.silhouettes && undefined === (silhouettes = this.readSilhouettes(json.silhouettes)))
647
- return { succeeded };
648
- if (undefined !== json.polylines && undefined === (polylines = this.readTesselatedPolyline(json.polylines)))
649
- return { succeeded };
650
- if (undefined !== json.indexed && undefined === (indexed = this.readIndexedEdges(json.indexed)))
651
- return { succeeded };
652
- succeeded = true;
653
- let params;
654
- if (segments || silhouettes || polylines || indexed) {
655
- params = {
656
- segments,
657
- silhouettes,
658
- polylines,
659
- indexed,
660
- weight: displayParams.width,
661
- linePixels: displayParams.linePixels,
662
- };
663
- }
664
- return { succeeded, params };
665
44
  }
666
- readPrimitiveParams(primitive) {
667
- const materialName = primitive.material ?? "";
668
- const materialValue = 0 < materialName.length ? JsonUtils.asObject(this._materialValues[materialName]) : undefined;
669
- const displayParams = undefined !== materialValue ? this.createDisplayParams(materialValue) : undefined;
670
- if (undefined === displayParams)
671
- return undefined;
672
- const vertices = this.readVertexTable(primitive);
673
- if (undefined === vertices) {
674
- assert(false, "bad vertex table in tile data.");
675
- return undefined;
676
- }
677
- const viOrigin = primitive.viewIndependentOrigin ? Point3d.fromJSON(primitive.viewIndependentOrigin) : undefined;
678
- const isPlanar = !this._is3d || JsonUtils.asBool(primitive.isPlanar);
679
- switch (primitive.type) {
680
- case Mesh.PrimitiveType.Mesh: {
681
- const surface = this.readSurface(primitive, displayParams);
682
- if (!surface)
683
- return undefined;
684
- // ###TODO: Tile generator shouldn't bother producing edges for classification meshes in the first place...
685
- let edgeParams;
686
- if (this._loadEdges && undefined !== primitive.edges && SurfaceType.VolumeClassifier !== surface.type) {
687
- const edgeResult = this.readEdges(primitive.edges, displayParams);
688
- if (!edgeResult.succeeded)
689
- return undefined;
690
- else
691
- edgeParams = edgeResult.params;
692
- }
693
- return {
694
- params: new MeshParams(vertices, surface, edgeParams, isPlanar, this.readAuxChannelTable(primitive)),
695
- type: "mesh",
696
- viOrigin,
697
- };
698
- }
699
- case Mesh.PrimitiveType.Polyline: {
700
- const polyline = this.readTesselatedPolyline(primitive);
701
- if (!polyline)
702
- return undefined;
703
- let flags = PolylineTypeFlags.Normal;
704
- if (DisplayParams.RegionEdgeType.Outline === displayParams.regionEdgeType)
705
- flags = (undefined === displayParams.gradient || displayParams.gradient.isOutlined) ? PolylineTypeFlags.Edge : PolylineTypeFlags.Outline;
706
- return {
707
- params: new PolylineParams(vertices, polyline, displayParams.width, displayParams.linePixels, isPlanar, flags),
708
- type: "polyline",
709
- viOrigin,
710
- };
711
- }
712
- case Mesh.PrimitiveType.Point: {
713
- const indices = this.readVertexIndices(primitive.indices);
714
- if (undefined === indices)
715
- return undefined;
716
- return {
717
- params: new PointStringParams(vertices, indices, displayParams.width),
718
- type: "point",
719
- viOrigin,
720
- };
721
- }
722
- default:
723
- assert(false, "unhandled primitive type");
724
- return undefined;
725
- }
726
- }
727
- readPrimitiveGeometry(primitive) {
728
- const prim = this.readPrimitiveParams(primitive);
729
- return prim ? this.createPrimitiveGeometry(prim) : undefined;
730
- }
731
- createPrimitiveGeometry(prim) {
732
- switch (prim.type) {
733
- case "mesh":
734
- return this._system.createMeshGeometry(prim.params, prim.viOrigin);
735
- case "polyline":
736
- return this._system.createPolylineGeometry(prim.params, prim.viOrigin);
737
- case "point":
738
- return this._system.createPointStringGeometry(prim.params, prim.viOrigin);
739
- }
740
- }
741
- getPatternGeometry(patternName) {
742
- let geometry = this._patternGeometry.get(patternName);
743
- if (geometry)
744
- return geometry;
745
- const symbol = this._patternSymbols[patternName];
746
- if (!symbol)
747
- return undefined;
748
- geometry = [];
749
- for (const primitive of symbol.primitives) {
750
- const geom = this.readPrimitiveGeometry(primitive);
751
- if (geom)
752
- geometry.push(geom);
753
- }
754
- this._patternGeometry.set(patternName, geometry);
755
- return geometry;
756
- }
757
- readAnimationBranches(output, mesh, featureTable, timeline) {
758
- const primitives = mesh.primitives;
759
- if (!primitives)
760
- return;
761
- const branchesByNodeId = new Map();
762
- const getBranch = (nodeId) => {
763
- let branch = branchesByNodeId.get(nodeId);
764
- if (!branch) {
765
- branchesByNodeId.set(nodeId, branch = new GraphicBranch(true));
766
- branch.animationNodeId = nodeId;
767
- branch.animationId = `${this._modelId}_Node_${nodeId}`;
768
- }
769
- return branch;
770
- };
771
- featureTable.populateAnimationNodeIds((feature) => timeline.getBatchIdForFeature(feature), timeline.maxBatchId);
772
- const discreteNodeIds = timeline.discreteBatchIds;
773
- const computeNodeId = (featureIndex) => {
774
- const nodeId = featureTable.getAnimationNodeId(featureIndex);
775
- return 0 !== nodeId && discreteNodeIds.has(nodeId) ? nodeId : 0;
776
- };
777
- const splitArgs = {
778
- maxDimension: this._system.maxTextureSize,
779
- computeNodeId,
780
- featureTable,
781
- };
782
- for (const primitive of primitives) {
783
- if (primitive.type === "areaPattern") {
784
- // ###TODO animated area patterns.
785
- const gf = this.readAreaPattern(primitive);
786
- if (gf)
787
- getBranch(AnimationNodeId.Untransformed).add(gf);
788
- }
789
- else {
790
- const prim = this.readPrimitiveParams(primitive);
791
- if (!prim)
792
- continue;
793
- const viOrigin = prim.viOrigin;
794
- switch (prim.type) {
795
- case "mesh": {
796
- const split = splitMeshParams({ ...splitArgs, params: prim.params });
797
- for (const [nodeId, params] of split) {
798
- const geometry = this.createPrimitiveGeometry({ params, viOrigin, type: "mesh" });
799
- const instances = undefined; // ###TODO support splitting instances (currently animation tile trees do not permit instancing).
800
- const graphic = geometry ? this._system.createRenderGraphic(geometry, instances) : undefined;
801
- if (graphic)
802
- getBranch(nodeId).add(graphic);
803
- }
804
- break;
805
- }
806
- case "point": {
807
- const split = splitPointStringParams({ ...splitArgs, params: prim.params });
808
- for (const [nodeId, params] of split) {
809
- const geometry = this.createPrimitiveGeometry({ params, viOrigin, type: "point" });
810
- const instances = undefined; // ###TODO support splitting instances (currently animation tile trees do not permit instancing).
811
- const graphic = geometry ? this._system.createRenderGraphic(geometry, instances) : undefined;
812
- if (graphic)
813
- getBranch(nodeId).add(graphic);
814
- }
815
- break;
816
- }
817
- case "polyline": {
818
- const split = splitPolylineParams({ ...splitArgs, params: prim.params });
819
- for (const [nodeId, params] of split) {
820
- const geometry = this.createPrimitiveGeometry({ params, viOrigin, type: "polyline" });
821
- const instances = undefined; // ###TODO support splitting instances (currently animation tile trees do not permit instancing).
822
- const graphic = geometry ? this._system.createRenderGraphic(geometry, instances) : undefined;
823
- if (graphic)
824
- getBranch(nodeId).add(graphic);
825
- }
826
- break;
827
- }
828
- }
829
- }
830
- }
831
- for (const branch of branchesByNodeId.values()) {
832
- assert(!branch.isEmpty);
833
- output.push(this._system.createBranch(branch, Transform.createIdentity()));
834
- }
835
- }
836
- readBranch(output, primitives, nodeId, animationId) {
837
- const branch = new GraphicBranch(true);
838
- branch.animationId = animationId;
839
- branch.animationNodeId = nodeId;
840
- for (const primitive of primitives) {
841
- const graphic = this.readMeshGraphic(primitive);
842
- if (graphic)
843
- branch.add(graphic);
844
- }
845
- if (!branch.isEmpty)
846
- output.push(this._system.createBranch(branch, Transform.createIdentity()));
847
- }
848
- finishRead(isLeaf, featureTable, contentRange, emptySubRangeMask, sizeMultiplier) {
849
- const graphics = [];
850
- if (undefined === this._nodes.Node_Root) {
851
- // Unstructured -- prior to animation support....
852
- for (const meshKey of Object.keys(this._meshes)) {
853
- const meshValue = this._meshes[meshKey];
854
- const primitives = meshValue?.primitives;
855
- if (!primitives || !meshValue)
856
- continue;
857
- for (const primitive of primitives) {
858
- const graphic = this.readMeshGraphic(primitive);
859
- if (undefined !== graphic)
860
- graphics.push(graphic);
861
- }
862
- }
863
- }
864
- else {
865
- for (const nodeKey of Object.keys(this._nodes)) {
866
- const nodeValue = this._nodes[nodeKey];
867
- const meshValue = undefined !== nodeValue ? this._meshes[nodeValue] : undefined;
868
- const primitives = meshValue?.primitives;
869
- if (!primitives || !meshValue)
870
- continue;
871
- const layerId = meshValue.layer;
872
- if ("Node_Root" === nodeKey) {
873
- if (this._timeline) {
874
- // Split up the root node into transform nodes.
875
- this.readAnimationBranches(graphics, meshValue, featureTable, this._timeline);
876
- }
877
- else if (this._containsTransformNodes) {
878
- // If transform nodes exist in the tile tree, then we need to create a branch for Node_Root so that elements not associated with
879
- // any node in the schedule script can be grouped together.
880
- this.readBranch(graphics, primitives, AnimationNodeId.Untransformed, undefined);
881
- }
882
- else {
883
- for (const primitive of primitives) {
884
- const graphic = this.readMeshGraphic(primitive);
885
- if (undefined !== graphic)
886
- graphics.push(graphic);
887
- }
888
- }
889
- }
890
- else if (undefined === layerId) {
891
- this.readBranch(graphics, primitives, extractNodeId(nodeKey), `${this._modelId}_${nodeKey}`);
892
- }
893
- else {
894
- const layerGraphics = [];
895
- for (const primitive of primitives) {
896
- const graphic = this.readMeshGraphic(primitive);
897
- if (undefined !== graphic)
898
- layerGraphics.push(graphic);
899
- }
900
- if (layerGraphics.length > 0) {
901
- const layerGraphic = 1 === layerGraphics.length ? layerGraphics[0] : this._system.createGraphicList(layerGraphics);
902
- graphics.push(this._system.createGraphicLayer(layerGraphic, layerId));
903
- }
904
- }
905
- }
906
- }
907
- let tileGraphic;
908
- switch (graphics.length) {
909
- case 0:
910
- break;
911
- case 1:
912
- tileGraphic = graphics[0];
913
- break;
914
- default:
915
- tileGraphic = this._system.createGraphicList(graphics);
916
- break;
917
- }
918
- if (tileGraphic && false !== this._options)
919
- tileGraphic = this._system.createBatch(tileGraphic, featureTable, contentRange, this._options);
920
- if (tileGraphic && this._rtcCenter) {
921
- const rtcBranch = new GraphicBranch(true);
922
- rtcBranch.add(tileGraphic);
923
- tileGraphic = this._system.createBranch(rtcBranch, Transform.createTranslation(this._rtcCenter));
924
- }
45
+ catch (e) {
46
+ if (e instanceof TileReadError)
47
+ return { isLeaf: true, readStatus: e.errorNumber };
48
+ else
49
+ throw e;
50
+ }
51
+ args.stream.reset();
52
+ const document = parseImdlDocument({
53
+ stream: args.stream,
54
+ batchModelId: args.modelId,
55
+ is3d: args.is3d,
56
+ maxVertexTableSize: IModelApp.renderSystem.maxTextureSize,
57
+ omitEdges: false === args.loadEdges,
58
+ timeline: args.timeline,
59
+ createUntransformedRootNode: args.containsTransformNodes,
60
+ });
61
+ if (typeof document === "number")
62
+ return { isLeaf: true, readStatus: document };
63
+ let graphic = await decodeImdlGraphics({
64
+ system: args.system,
65
+ iModel: args.iModel,
66
+ document,
67
+ isCanceled: args.isCanceled,
68
+ });
69
+ if (args.isCanceled && args.isCanceled())
70
+ return { isLeaf: true, readStatus: TileReadStatus.Canceled };
71
+ if (graphic && false !== args.options) {
72
+ const featureTable = convertFeatureTable(document.featureTable, args.modelId);
73
+ graphic = args.system.createBatch(graphic, featureTable, content.contentRange, args.options);
74
+ }
75
+ if (graphic && document.rtcCenter) {
76
+ const rtcBranch = new GraphicBranch(true);
77
+ rtcBranch.add(graphic);
78
+ graphic = args.system.createBranch(rtcBranch, Transform.createTranslation(Point3d.fromJSON(document.rtcCenter)));
79
+ }
80
+ return {
81
+ readStatus: TileReadStatus.Success,
82
+ isLeaf: content.isLeaf,
83
+ sizeMultiplier: content.sizeMultiplier,
84
+ contentRange: content.contentRange.isNull ? undefined : content.contentRange,
85
+ graphic,
86
+ emptySubRangeMask: content.emptySubRangeMask,
87
+ };
88
+ }
89
+ /** @internal */
90
+ export var ImdlReader;
91
+ (function (ImdlReader) {
92
+ function create(args) {
925
93
  return {
926
- readStatus: TileReadStatus.Success,
927
- isLeaf,
928
- sizeMultiplier,
929
- contentRange: contentRange.isNull ? undefined : contentRange,
930
- graphic: tileGraphic,
931
- emptySubRangeMask,
94
+ read: async () => readImdlContent(args),
932
95
  };
933
96
  }
934
- }
97
+ ImdlReader.create = create;
98
+ })(ImdlReader || (ImdlReader = {}));
935
99
  //# sourceMappingURL=ImdlReader.js.map