bruce-cesium 5.8.3 → 5.8.5

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.
@@ -1,6 +1,6 @@
1
- import { BruceEvent, Cartes, Entity as Entity$1, ProjectViewTile, Carto, Geometry, MathUtils, LRUCache, Api, Calculator, ClientFile, EntityTag, EntityType, ObjectUtils, Style, DelayQueue, EntityLod, Bounds, ZoomControl, EntityRelationType, ENVIRONMENT, EntityHistoricData, Tileset, EntityCoords, DataLab, EntitySource, MenuItem, EntityRelation, ProgramKey, ProjectView, ProjectViewBookmark, Camera, ProjectViewLegacyTile, EntityAttachment, EntityAttachmentType, EntityAttribute, AbstractApi, Session } from 'bruce-models';
1
+ import { BruceEvent, Cartes, Entity as Entity$1, ProjectViewTile, Carto, Geometry, MathUtils, LRUCache, Api, Calculator, ClientFile, EntityTag, EntityType, ObjectUtils, Style, DelayQueue, EntityLod, Bounds, ZoomControl, EntityRelationType, ENVIRONMENT, MenuItem, EntityHistoricData, Tileset, EntityCoords, DataLab, EntitySource, EntityRelation, ProgramKey, ProjectView, ProjectViewBookmark, Camera, ProjectViewLegacyTile, EntityAttachment, EntityAttachmentType, EntityAttribute, AbstractApi, Session } from 'bruce-models';
2
2
  import * as Cesium from 'cesium';
3
- import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, JulianDate, Entity, DistanceDisplayCondition, ClassificationType, ArcType, CornerType, ShadowMode, ConstantProperty, ConstantPositionProperty, PolygonHierarchy, PolylineGraphics, ColorMaterialProperty, ColorBlendMode, HeadingPitchRoll, Transforms, Model, HorizontalOrigin, VerticalOrigin, SceneMode, Primitive, Cesium3DTileFeature, GeoJsonDataSource, Cesium3DTileStyle, HeadingPitchRange, Ion, Cesium3DTileColorBlendMode, KmlDataSource, Quaternion, Matrix3, Matrix4, OrthographicFrustum, EasingFunction, NearFarScalar, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, IonResource, Cesium3DTileset, CesiumInspector, defined, ClockRange, EllipsoidGeodesic, sampleTerrainMostDetailed, PolygonPipeline, SceneTransforms, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, ScreenSpaceEventHandler, ScreenSpaceEventType, BoundingSphere, GeometryInstance, CzmlDataSource, Intersect, Fullscreen } from 'cesium';
3
+ import { Cartographic, Cartesian2, Math as Math$1, Cartesian3, CallbackProperty, Color, HeightReference, Rectangle, JulianDate, Entity, DistanceDisplayCondition, ClassificationType, ArcType, CornerType, ShadowMode, ConstantProperty, ConstantPositionProperty, HorizontalOrigin, VerticalOrigin, PolygonHierarchy, PolylineGraphics, ColorMaterialProperty, ColorBlendMode, HeadingPitchRoll, Transforms, Model, SceneMode, Primitive, Cesium3DTileFeature, GeoJsonDataSource, Cesium3DTileStyle, HeadingPitchRange, Ion, Cesium3DTileColorBlendMode, KmlDataSource, Quaternion, Matrix3, Matrix4, SceneTransforms, OrthographicFrustum, EasingFunction, NearFarScalar, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, IonResource, Cesium3DTileset, CesiumInspector, defined, ClockRange, EllipsoidGeodesic, sampleTerrainMostDetailed, PolygonPipeline, BoundingSphere, GeometryInstance, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, ScreenSpaceEventHandler, ScreenSpaceEventType, CzmlDataSource, Intersect, Fullscreen } from 'cesium';
4
4
 
5
5
  const TIME_LAG = 300;
6
6
  const POSITION_CHECK_TIMER = 950;
@@ -3449,6 +3449,9 @@ var EntityUtils;
3449
3449
  latestDate = historicDetails.DateTime;
3450
3450
  }
3451
3451
  }
3452
+ // Hacky lookup for Entity ID -> related Tileset coords that are currently active.
3453
+ // This helps find ones that are modified due to being historic/moving and apply an Entity's local movement against them.
3454
+ const entityIdTilesetCoords = new Map();
3452
3455
  const data = {
3453
3456
  pos3d: null,
3454
3457
  rectangle: null,
@@ -3532,7 +3535,7 @@ var EntityUtils;
3532
3535
  * Returns an array of positions from the entity's currently rendered graphics.
3533
3536
  */
3534
3537
  const evaluateRendered = async () => {
3535
- var _a, _b, _c;
3538
+ var _a, _b;
3536
3539
  const rego = visualRegister ? visualRegister.GetRego({
3537
3540
  entityId: sample.entityId,
3538
3541
  menuItemId: sample.menuItemId
@@ -3555,19 +3558,26 @@ var EntityUtils;
3555
3558
  // Get the Tileset.
3556
3559
  const tileset = rego.visual.tileset;
3557
3560
  if (tileset === null || tileset === void 0 ? void 0 : tileset._bruceCoords) {
3561
+ // Record so we can use it during record evaluation instead of rendered evaluation.
3562
+ entityIdTilesetCoords.set(entityId, tileset._bruceCoords);
3563
+ return [];
3558
3564
  // The render logic currently swaps out the UCS location when the assembly is moving.
3559
- const location = (_c = tileset._bruceCoords.ucs) === null || _c === void 0 ? void 0 : _c.location;
3560
- if (location) {
3561
- const latitude = EnsureNumber(location.latitude);
3562
- const longitude = EnsureNumber(location.longitude);
3563
- // Disallowing 0.
3564
- if (latitude && longitude) {
3565
- const pos3d = Cartesian3.fromDegrees(longitude, latitude, EnsureNumber(location.altitude));
3566
- const toAdjust = [pos3d];
3567
- await ensureHeightRefs(toAdjust, sample);
3568
- return toAdjust;
3569
- }
3570
- }
3565
+ // const location = tileset._bruceCoords.ucs?.location;
3566
+ // if (location) {
3567
+ // const latitude = EnsureNumber(location.latitude);
3568
+ // const longitude = EnsureNumber(location.longitude);
3569
+ // // Disallowing 0.
3570
+ // if (latitude && longitude) {
3571
+ // const pos3d = Cesium.Cartesian3.fromDegrees(longitude, latitude, EnsureNumber(location.altitude));
3572
+ // console.log("using tileset pos3d for historic entity", {
3573
+ // pos3d: pos3d,
3574
+ // entity:
3575
+ // })
3576
+ // const toAdjust = [pos3d];
3577
+ // await ensureHeightRefs(toAdjust, sample);
3578
+ // return toAdjust;
3579
+ // }
3580
+ // }
3571
3581
  }
3572
3582
  }
3573
3583
  let posses = [];
@@ -3719,7 +3729,7 @@ var EntityUtils;
3719
3729
  * @param sample
3720
3730
  */
3721
3731
  const getRecordEntityPositions = async (sample) => {
3722
- var _a, _b, _c;
3732
+ var _a, _b, _c, _d;
3723
3733
  let { entityId, entity, disallowRendered } = sample;
3724
3734
  const isAssemblyEntity = ((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.AssemblyRootLocation) != null;
3725
3735
  /**
@@ -3799,6 +3809,74 @@ var EntityUtils;
3799
3809
  return posses;
3800
3810
  };
3801
3811
  if (isAssemblyEntity) {
3812
+ // See if we have tileset coords to use.
3813
+ // This means we have to hack fly-to for a historic/moving assembly.
3814
+ {
3815
+ const tCoords = entityIdTilesetCoords.get(entityId);
3816
+ const location = (_b = tCoords === null || tCoords === void 0 ? void 0 : tCoords.ucs) === null || _b === void 0 ? void 0 : _b.location;
3817
+ if (tCoords && location) {
3818
+ const latitude = EnsureNumber(location.latitude);
3819
+ const longitude = EnsureNumber(location.longitude);
3820
+ if (latitude && longitude) {
3821
+ const worldPosition = entity.Bruce.AssemblyWorldPosition;
3822
+ if (worldPosition) {
3823
+ const offset = new Cartesian3(+worldPosition[0][3], +worldPosition[1][3], +worldPosition[2][3]);
3824
+ const transform = tCoords.transform;
3825
+ let heading = 0;
3826
+ if (+transform.heading) {
3827
+ heading = +transform.heading;
3828
+ }
3829
+ let pitch = 0;
3830
+ if (+transform.pitch) {
3831
+ pitch = +transform.pitch;
3832
+ }
3833
+ let roll = 0;
3834
+ if (+transform.roll) {
3835
+ roll = +transform.roll;
3836
+ }
3837
+ let pos3d = Cartesian3.fromDegrees(EnsureNumber(longitude), EnsureNumber(latitude), EnsureNumber(location.altitude));
3838
+ const m1 = Transforms.eastNorthUpToFixedFrame(pos3d);
3839
+ const hpr = HeadingPitchRoll.fromDegrees(EnsureNumber(heading), EnsureNumber(pitch), EnsureNumber(roll), new HeadingPitchRoll());
3840
+ const transformHpr = Matrix3.fromHeadingPitchRoll(hpr);
3841
+ const transformedOffset = Matrix3.multiplyByVector(transformHpr, offset, new Cartesian3());
3842
+ pos3d = Matrix4.multiplyByPoint(m1, transformedOffset, new Cartesian3());
3843
+ pos3d = await processPosHeight(pos3d, HeightReference.NONE);
3844
+ const geometryRadius = Entity$1.GetValue({
3845
+ entity: entity,
3846
+ path: ["Bruce", "GeometryRadius"]
3847
+ });
3848
+ if (geometryRadius && (pos3d === null || pos3d === void 0 ? void 0 : pos3d.x)) {
3849
+ const sphere = BoundingSphere.fromPoints([pos3d]);
3850
+ // For now making sure it's less than x amount because we had a bug which made it huge.
3851
+ if (geometryRadius && geometryRadius < 500 && geometryRadius > 0.1) {
3852
+ sphere.radius = geometryRadius;
3853
+ spheres.push(sphere);
3854
+ }
3855
+ }
3856
+ return [pos3d];
3857
+ }
3858
+ else {
3859
+ if (location) {
3860
+ let pos3d = Cartesian3.fromDegrees(longitude, latitude, EnsureNumber(location.altitude));
3861
+ pos3d = await processPosHeight(pos3d, HeightReference.NONE);
3862
+ const geometryRadius = Entity$1.GetValue({
3863
+ entity: entity,
3864
+ path: ["Bruce", "GeometryRadius"]
3865
+ });
3866
+ if (geometryRadius && (pos3d === null || pos3d === void 0 ? void 0 : pos3d.x)) {
3867
+ const sphere = BoundingSphere.fromPoints([pos3d]);
3868
+ // For now making sure it's less than x amount because we had a bug which made it huge.
3869
+ if (geometryRadius && geometryRadius < 500 && geometryRadius > 0.1) {
3870
+ sphere.radius = geometryRadius;
3871
+ spheres.push(sphere);
3872
+ }
3873
+ }
3874
+ return [pos3d];
3875
+ }
3876
+ }
3877
+ }
3878
+ }
3879
+ }
3802
3880
  let pos3d = null;
3803
3881
  if (modelSpace) {
3804
3882
  pos3d = calcEntityLocation(entity, modelSpace);
@@ -3808,7 +3886,7 @@ var EntityUtils;
3808
3886
  entity: entity,
3809
3887
  path: ["Bruce", "Location"]
3810
3888
  });
3811
- if (eLocation != null && ((_b = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _b === void 0 ? void 0 : _b.AssemblyRootLocation) != null) {
3889
+ if (eLocation != null && ((_c = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _c === void 0 ? void 0 : _c.AssemblyRootLocation) != null) {
3812
3890
  pos3d = Cartesian3.fromDegrees(EnsureNumber(eLocation.longitude), EnsureNumber(eLocation.latitude), EnsureNumber(eLocation.altitude));
3813
3891
  }
3814
3892
  }
@@ -3839,7 +3917,7 @@ var EntityUtils;
3839
3917
  entity: entity,
3840
3918
  path: ["Bruce", "Location"]
3841
3919
  });
3842
- if ((eLocation === null || eLocation === void 0 ? void 0 : eLocation.longitude) && ((_c = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _c === void 0 ? void 0 : _c.AssemblyRootLocation) != null) {
3920
+ if ((eLocation === null || eLocation === void 0 ? void 0 : eLocation.longitude) && ((_d = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _d === void 0 ? void 0 : _d.AssemblyRootLocation) != null) {
3843
3921
  pos3d = Cartesian3.fromDegrees(EnsureNumber(eLocation.longitude), EnsureNumber(eLocation.latitude), EnsureNumber(eLocation.altitude));
3844
3922
  if (pos3d === null || pos3d === void 0 ? void 0 : pos3d.x) {
3845
3923
  pos3d = await processPosHeight(pos3d, HeightReference.NONE);
@@ -12196,6 +12274,41 @@ var VisualsRegister;
12196
12274
  }
12197
12275
  return map;
12198
12276
  }
12277
+ /**
12278
+ * Gets hierarchy information for a given entity from any render manager.
12279
+ * This is a utility method to get parent/child relationships.
12280
+ * @param entityId The entity ID to get hierarchy info for
12281
+ * @param menuItemId The menu item ID (optional)
12282
+ * @returns Hierarchy information or null if not found
12283
+ */
12284
+ getHierarchyInfo(entityId, menuItemId) {
12285
+ // Try to find the render manager for this entity
12286
+ const rego = this.GetRego({ entityId, menuItemId });
12287
+ if (!rego) {
12288
+ return null;
12289
+ }
12290
+ // Check if it's a CAD tileset
12291
+ if (rego.tilesetType === "CAD") {
12292
+ // This would need to be implemented in the CAD render manager
12293
+ // For now, return basic info
12294
+ return {
12295
+ parentId: undefined,
12296
+ children: [],
12297
+ path: [entityId]
12298
+ };
12299
+ }
12300
+ // Check if it's an Assembly
12301
+ if (rego.menuItemType === MenuItem.EType.Assembly) {
12302
+ // This would need to be implemented in the Assembly render manager
12303
+ // For now, return basic info
12304
+ return {
12305
+ parentId: undefined,
12306
+ children: [],
12307
+ path: [entityId]
12308
+ };
12309
+ }
12310
+ return null;
12311
+ }
12199
12312
  }
12200
12313
  VisualsRegister.Register = Register;
12201
12314
  })(VisualsRegister || (VisualsRegister = {}));
@@ -18422,7 +18535,11 @@ var TilesetCadRenderManager;
18422
18535
  buildModelTreeNodes(modelTree) {
18423
18536
  this.treeNodeByGeomId = {};
18424
18537
  this.treeNodeByEntityId = {};
18425
- const recurse = (node, firstFoundCollapsedBranch) => {
18538
+ const stack = [
18539
+ { node: modelTree, parentId: null, firstFoundCollapsedBranch: null }
18540
+ ];
18541
+ while (stack.length > 0) {
18542
+ const { node, parentId, firstFoundCollapsedBranch } = stack.pop();
18426
18543
  if (firstFoundCollapsedBranch) {
18427
18544
  this.treeNodeByGeomId[node.geomId] = firstFoundCollapsedBranch;
18428
18545
  this.treeNodeByEntityId[node.id] = firstFoundCollapsedBranch;
@@ -18432,21 +18549,27 @@ var TilesetCadRenderManager;
18432
18549
  entityId: node.id,
18433
18550
  typeId: node.typeId,
18434
18551
  name: node.name,
18435
- geomId: node.geomId
18552
+ geomId: node.geomId,
18553
+ parentId: parentId
18436
18554
  };
18437
18555
  this.treeNodeByGeomId[node.geomId] = cache;
18438
18556
  this.treeNodeByEntityId[node.id] = cache;
18557
+ let newFirstFoundCollapsedBranch = firstFoundCollapsedBranch;
18439
18558
  if (!firstFoundCollapsedBranch && node.collapsed) {
18440
- firstFoundCollapsedBranch = cache;
18441
- }
18442
- }
18443
- if (node.children) {
18444
- for (let i = 0; i < node.children.length; i++) {
18445
- recurse(node.children[i], firstFoundCollapsedBranch);
18559
+ newFirstFoundCollapsedBranch = cache;
18560
+ }
18561
+ // Push children to stack in reverse order to maintain correct traversal
18562
+ if (node.children) {
18563
+ for (let i = node.children.length - 1; i >= 0; i--) {
18564
+ stack.push({
18565
+ node: node.children[i],
18566
+ parentId: node.id,
18567
+ firstFoundCollapsedBranch: newFirstFoundCollapsedBranch
18568
+ });
18569
+ }
18446
18570
  }
18447
18571
  }
18448
- };
18449
- recurse(modelTree, null);
18572
+ }
18450
18573
  }
18451
18574
  getEntityTypeByPath(path) {
18452
18575
  var _a, _b;
@@ -18465,6 +18588,236 @@ var TilesetCadRenderManager;
18465
18588
  const node = this.treeNodeByEntityId[entityId] || null;
18466
18589
  return node ? node.typeId : null;
18467
18590
  }
18591
+ /**
18592
+ * Gets the parent node of a given entity.
18593
+ * @param entityId The entity ID to find the parent for
18594
+ * @returns The parent node or null if no parent exists
18595
+ */
18596
+ getParentNode(entityId) {
18597
+ var _a, _b;
18598
+ if (this.treeNodeByEntityId == null) {
18599
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18600
+ if (!modelTree) {
18601
+ modelTree = this.modelTree;
18602
+ }
18603
+ if (!modelTree) {
18604
+ return null;
18605
+ }
18606
+ this.buildModelTreeNodes(modelTree);
18607
+ }
18608
+ const node = this.treeNodeByEntityId[entityId];
18609
+ if (node === null || node === void 0 ? void 0 : node.parentId) {
18610
+ return this.treeNodeByEntityId[node.parentId] || null;
18611
+ }
18612
+ return null;
18613
+ }
18614
+ /**
18615
+ * Gets all child nodes of a given entity.
18616
+ * @param entityId The entity ID to find children for
18617
+ * @returns Array of child nodes
18618
+ */
18619
+ getChildNodes(entityId) {
18620
+ var _a, _b;
18621
+ if (this.treeNodeByEntityId == null) {
18622
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18623
+ if (!modelTree) {
18624
+ modelTree = this.modelTree;
18625
+ }
18626
+ if (!modelTree) {
18627
+ return [];
18628
+ }
18629
+ this.buildModelTreeNodes(modelTree);
18630
+ }
18631
+ const children = [];
18632
+ for (const nodeId in this.treeNodeByEntityId) {
18633
+ const node = this.treeNodeByEntityId[nodeId];
18634
+ if (node.parentId === entityId) {
18635
+ children.push(node);
18636
+ }
18637
+ }
18638
+ return children;
18639
+ }
18640
+ /**
18641
+ * Gets all descendant nodes of a given entity (children, grandchildren, etc.).
18642
+ * @param entityId The entity ID to find descendants for
18643
+ * @returns Array of descendant nodes
18644
+ */
18645
+ getDescendantNodes(entityId) {
18646
+ var _a, _b;
18647
+ if (this.treeNodeByEntityId == null) {
18648
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18649
+ if (!modelTree) {
18650
+ modelTree = this.modelTree;
18651
+ }
18652
+ if (!modelTree) {
18653
+ return [];
18654
+ }
18655
+ this.buildModelTreeNodes(modelTree);
18656
+ }
18657
+ const descendants = [];
18658
+ const stack = [entityId];
18659
+ // Use iterative approach with a stack instead of recursion
18660
+ while (stack.length > 0) {
18661
+ const currentId = stack.pop();
18662
+ if (!currentId)
18663
+ continue;
18664
+ for (const nodeId in this.treeNodeByEntityId) {
18665
+ const node = this.treeNodeByEntityId[nodeId];
18666
+ if (node.parentId === currentId) {
18667
+ descendants.push(node);
18668
+ stack.push(node.entityId);
18669
+ }
18670
+ }
18671
+ }
18672
+ return descendants;
18673
+ }
18674
+ /**
18675
+ * Gets the root node of the model tree.
18676
+ * @returns The root node or null if no tree exists
18677
+ */
18678
+ getRootNode() {
18679
+ var _a, _b;
18680
+ if (this.treeNodeByEntityId == null) {
18681
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18682
+ if (!modelTree) {
18683
+ modelTree = this.modelTree;
18684
+ }
18685
+ if (!modelTree) {
18686
+ return null;
18687
+ }
18688
+ this.buildModelTreeNodes(modelTree);
18689
+ }
18690
+ // Find the node with no parent (root node)
18691
+ for (const nodeId in this.treeNodeByEntityId) {
18692
+ const node = this.treeNodeByEntityId[nodeId];
18693
+ if (!node.parentId) {
18694
+ return node;
18695
+ }
18696
+ }
18697
+ return null;
18698
+ }
18699
+ /**
18700
+ * Gets the path from root to a given entity.
18701
+ * @param entityId The entity ID to find the path for
18702
+ * @returns Array of node IDs representing the path from root to the entity
18703
+ */
18704
+ getNodePath(entityId) {
18705
+ var _a, _b;
18706
+ if (this.treeNodeByEntityId == null) {
18707
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18708
+ if (!modelTree) {
18709
+ modelTree = this.modelTree;
18710
+ }
18711
+ if (!modelTree) {
18712
+ return [];
18713
+ }
18714
+ this.buildModelTreeNodes(modelTree);
18715
+ }
18716
+ const path = [];
18717
+ let currentId = entityId;
18718
+ while (currentId) {
18719
+ const node = this.treeNodeByEntityId[currentId];
18720
+ if (!node) {
18721
+ break;
18722
+ }
18723
+ path.unshift(currentId);
18724
+ currentId = node.parentId;
18725
+ }
18726
+ return path;
18727
+ }
18728
+ /**
18729
+ * Batch operation to get multiple node paths efficiently.
18730
+ * @param entityIds Array of entity IDs to get paths for
18731
+ * @returns Map of entityId to path array
18732
+ */
18733
+ getNodePathsBatch(entityIds) {
18734
+ var _a, _b;
18735
+ if (this.treeNodeByEntityId == null) {
18736
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18737
+ if (!modelTree) {
18738
+ modelTree = this.modelTree;
18739
+ }
18740
+ if (!modelTree) {
18741
+ return new Map();
18742
+ }
18743
+ this.buildModelTreeNodes(modelTree);
18744
+ }
18745
+ const paths = new Map();
18746
+ for (const entityId of entityIds) {
18747
+ const path = [];
18748
+ let currentId = entityId;
18749
+ while (currentId) {
18750
+ const node = this.treeNodeByEntityId[currentId];
18751
+ if (!node) {
18752
+ break;
18753
+ }
18754
+ path.unshift(currentId);
18755
+ currentId = node.parentId;
18756
+ }
18757
+ paths.set(entityId, path);
18758
+ }
18759
+ return paths;
18760
+ }
18761
+ /**
18762
+ * Batch operation to get multiple parent nodes efficiently.
18763
+ * @param entityIds Array of entity IDs to get parents for
18764
+ * @returns Map of entityId to parent node
18765
+ */
18766
+ getParentNodesBatch(entityIds) {
18767
+ var _a, _b;
18768
+ if (this.treeNodeByEntityId == null) {
18769
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18770
+ if (!modelTree) {
18771
+ modelTree = this.modelTree;
18772
+ }
18773
+ if (!modelTree) {
18774
+ return new Map();
18775
+ }
18776
+ this.buildModelTreeNodes(modelTree);
18777
+ }
18778
+ const parents = new Map();
18779
+ for (const entityId of entityIds) {
18780
+ const node = this.treeNodeByEntityId[entityId];
18781
+ if (node === null || node === void 0 ? void 0 : node.parentId) {
18782
+ parents.set(entityId, this.treeNodeByEntityId[node.parentId] || null);
18783
+ }
18784
+ else {
18785
+ parents.set(entityId, null);
18786
+ }
18787
+ }
18788
+ return parents;
18789
+ }
18790
+ /**
18791
+ * Batch operation to get multiple child nodes efficiently.
18792
+ * @param entityIds Array of entity IDs to get children for
18793
+ * @returns Map of entityId to array of child nodes
18794
+ */
18795
+ getChildNodesBatch(entityIds) {
18796
+ var _a, _b;
18797
+ if (this.treeNodeByEntityId == null) {
18798
+ let modelTree = (_b = (_a = this.cTileset) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.modelTree;
18799
+ if (!modelTree) {
18800
+ modelTree = this.modelTree;
18801
+ }
18802
+ if (!modelTree) {
18803
+ return new Map();
18804
+ }
18805
+ this.buildModelTreeNodes(modelTree);
18806
+ }
18807
+ const children = new Map();
18808
+ // Initialize all entityIds with empty arrays
18809
+ for (const entityId of entityIds) {
18810
+ children.set(entityId, []);
18811
+ }
18812
+ // Build a reverse lookup for efficiency
18813
+ for (const nodeId in this.treeNodeByEntityId) {
18814
+ const node = this.treeNodeByEntityId[nodeId];
18815
+ if (node.parentId && children.has(node.parentId)) {
18816
+ children.get(node.parentId).push(node);
18817
+ }
18818
+ }
18819
+ return children;
18820
+ }
18468
18821
  Dispose() {
18469
18822
  if (this.disposed) {
18470
18823
  return;
@@ -21997,6 +22350,8 @@ var AssemblyRenderManager;
21997
22350
  this.disposed = false;
21998
22351
  // Cache of the hierarchy so that our scene-tree can reference it.
21999
22352
  this.hierarchy = null;
22353
+ // Quick look-up of the hierarchy nodes by entity ID.
22354
+ this.hierarchyNodeByEntityId = null;
22000
22355
  this.modelSpace = false;
22001
22356
  const { viewer, register: visualsManager, getters, item } = params;
22002
22357
  this.viewer = viewer;
@@ -22024,6 +22379,8 @@ var AssemblyRenderManager;
22024
22379
  if (this.disposed) {
22025
22380
  return;
22026
22381
  }
22382
+ // Build hierarchy node cache for quick lookups
22383
+ this.buildHierarchyNodes(hierarchy);
22027
22384
  const traverseHierarchy = (node, leavesOnly) => {
22028
22385
  var _a;
22029
22386
  if (node.Children) {
@@ -22124,6 +22481,210 @@ var AssemblyRenderManager;
22124
22481
  entityIds = entities.map(x => { var _a; return (_a = x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; });
22125
22482
  }
22126
22483
  }
22484
+ /**
22485
+ * Builds quick look-up of the hierarchy nodes by entity ID.
22486
+ * @param hierarchy The hierarchy data from the API
22487
+ */
22488
+ buildHierarchyNodes(hierarchy) {
22489
+ this.hierarchyNodeByEntityId = {};
22490
+ if (!(hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.Root)) {
22491
+ return;
22492
+ }
22493
+ // Use iterative approach with a stack instead of recursion
22494
+ const stack = [
22495
+ { node: hierarchy.Root, parentId: null }
22496
+ ];
22497
+ while (stack.length > 0) {
22498
+ const { node, parentId } = stack.pop();
22499
+ if (node.ID) {
22500
+ const cache = {
22501
+ entityId: node.ID,
22502
+ name: node.Name || node.ID,
22503
+ parentId: parentId
22504
+ };
22505
+ this.hierarchyNodeByEntityId[node.ID] = cache;
22506
+ }
22507
+ // Push children to stack in reverse order to maintain correct traversal
22508
+ if (node.Children) {
22509
+ for (let i = node.Children.length - 1; i >= 0; i--) {
22510
+ stack.push({
22511
+ node: node.Children[i],
22512
+ parentId: node.ID
22513
+ });
22514
+ }
22515
+ }
22516
+ }
22517
+ }
22518
+ /**
22519
+ * Gets the parent node of a given entity.
22520
+ * @param entityId The entity ID to find the parent for
22521
+ * @returns The parent node or null if no parent exists
22522
+ */
22523
+ getParentNode(entityId) {
22524
+ var _a;
22525
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22526
+ this.buildHierarchyNodes(this.hierarchy);
22527
+ }
22528
+ const node = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[entityId];
22529
+ if (node === null || node === void 0 ? void 0 : node.parentId) {
22530
+ return this.hierarchyNodeByEntityId[node.parentId] || null;
22531
+ }
22532
+ return null;
22533
+ }
22534
+ /**
22535
+ * Gets all child nodes of a given entity.
22536
+ * @param entityId The entity ID to find children for
22537
+ * @returns Array of child nodes
22538
+ */
22539
+ getChildNodes(entityId) {
22540
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22541
+ this.buildHierarchyNodes(this.hierarchy);
22542
+ }
22543
+ const children = [];
22544
+ for (const nodeId in this.hierarchyNodeByEntityId) {
22545
+ const node = this.hierarchyNodeByEntityId[nodeId];
22546
+ if (node.parentId === entityId) {
22547
+ children.push(node);
22548
+ }
22549
+ }
22550
+ return children;
22551
+ }
22552
+ /**
22553
+ * Gets all descendant nodes of a given entity (children, grandchildren, etc.).
22554
+ * @param entityId The entity ID to find descendants for
22555
+ * @returns Array of descendant nodes
22556
+ */
22557
+ getDescendantNodes(entityId) {
22558
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22559
+ this.buildHierarchyNodes(this.hierarchy);
22560
+ }
22561
+ const descendants = [];
22562
+ const stack = [entityId];
22563
+ // Use iterative approach with a stack instead of recursion
22564
+ while (stack.length > 0) {
22565
+ const currentId = stack.pop();
22566
+ if (!currentId)
22567
+ continue;
22568
+ for (const nodeId in this.hierarchyNodeByEntityId) {
22569
+ const node = this.hierarchyNodeByEntityId[nodeId];
22570
+ if (node.parentId === currentId) {
22571
+ descendants.push(node);
22572
+ stack.push(node.entityId);
22573
+ }
22574
+ }
22575
+ }
22576
+ return descendants;
22577
+ }
22578
+ /**
22579
+ * Gets the root node of the hierarchy.
22580
+ * @returns The root node or null if no hierarchy exists
22581
+ */
22582
+ getRootNode() {
22583
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22584
+ this.buildHierarchyNodes(this.hierarchy);
22585
+ }
22586
+ // Find the node with no parent (root node)
22587
+ for (const nodeId in this.hierarchyNodeByEntityId) {
22588
+ const node = this.hierarchyNodeByEntityId[nodeId];
22589
+ if (!node.parentId) {
22590
+ return node;
22591
+ }
22592
+ }
22593
+ return null;
22594
+ }
22595
+ /**
22596
+ * Gets the path from root to a given entity.
22597
+ * @param entityId The entity ID to find the path for
22598
+ * @returns Array of node IDs representing the path from root to the entity
22599
+ */
22600
+ getNodePath(entityId) {
22601
+ var _a;
22602
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22603
+ this.buildHierarchyNodes(this.hierarchy);
22604
+ }
22605
+ const path = [];
22606
+ let currentId = entityId;
22607
+ while (currentId) {
22608
+ const node = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[currentId];
22609
+ if (!node) {
22610
+ break;
22611
+ }
22612
+ path.unshift(currentId);
22613
+ currentId = node.parentId;
22614
+ }
22615
+ return path;
22616
+ }
22617
+ /**
22618
+ * Batch operation to get multiple node paths efficiently.
22619
+ * @param entityIds Array of entity IDs to get paths for
22620
+ * @returns Map of entityId to path array
22621
+ */
22622
+ getNodePathsBatch(entityIds) {
22623
+ var _a;
22624
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22625
+ this.buildHierarchyNodes(this.hierarchy);
22626
+ }
22627
+ const paths = new Map();
22628
+ for (const entityId of entityIds) {
22629
+ const path = [];
22630
+ let currentId = entityId;
22631
+ while (currentId) {
22632
+ const node = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[currentId];
22633
+ if (!node) {
22634
+ break;
22635
+ }
22636
+ path.unshift(currentId);
22637
+ currentId = node.parentId;
22638
+ }
22639
+ paths.set(entityId, path);
22640
+ }
22641
+ return paths;
22642
+ }
22643
+ /**
22644
+ * Batch operation to get multiple parent nodes efficiently.
22645
+ * @param entityIds Array of entity IDs to get parents for
22646
+ * @returns Map of entityId to parent node
22647
+ */
22648
+ getParentNodesBatch(entityIds) {
22649
+ var _a;
22650
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22651
+ this.buildHierarchyNodes(this.hierarchy);
22652
+ }
22653
+ const parents = new Map();
22654
+ for (const entityId of entityIds) {
22655
+ const node = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[entityId];
22656
+ if (node === null || node === void 0 ? void 0 : node.parentId) {
22657
+ parents.set(entityId, this.hierarchyNodeByEntityId[node.parentId] || null);
22658
+ }
22659
+ else {
22660
+ parents.set(entityId, null);
22661
+ }
22662
+ }
22663
+ return parents;
22664
+ }
22665
+ /**
22666
+ * Batch operation to get multiple child nodes efficiently.
22667
+ * @param entityIds Array of entity IDs to get children for
22668
+ * @returns Map of entityId to array of child nodes
22669
+ */
22670
+ getChildNodesBatch(entityIds) {
22671
+ if (this.hierarchyNodeByEntityId == null && this.hierarchy) {
22672
+ this.buildHierarchyNodes(this.hierarchy);
22673
+ }
22674
+ const children = new Map();
22675
+ // Initialize all entityIds with empty arrays
22676
+ for (const entityId of entityIds) {
22677
+ children.set(entityId, []);
22678
+ }
22679
+ // Build a reverse lookup for efficiency
22680
+ for (const nodeId in this.hierarchyNodeByEntityId) {
22681
+ const node = this.hierarchyNodeByEntityId[nodeId];
22682
+ if (node.parentId && children.has(node.parentId)) {
22683
+ children.get(node.parentId).push(node);
22684
+ }
22685
+ }
22686
+ return children;
22687
+ }
22127
22688
  }
22128
22689
  AssemblyRenderManager.Manager = Manager;
22129
22690
  })(AssemblyRenderManager || (AssemblyRenderManager = {}));
@@ -32334,7 +32895,7 @@ class WidgetViewBar extends Widget.AWidget {
32334
32895
  }
32335
32896
  }
32336
32897
 
32337
- const VERSION = "5.8.3";
32898
+ const VERSION = "5.8.5";
32338
32899
 
32339
32900
  export { VERSION, CesiumViewMonitor, ViewerUtils, ViewerEventTracker, MenuItemManager, isOutlineChanged, EntityRenderEngine, EntityRenderEnginePoint, EntityRenderEnginePolyline, EntityRenderEnginePolygon, EntityRenderEngineModel3d, MenuItemCreator, VisualsRegister, RenderManager, EntitiesIdsRenderManager, DataLabRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, TilesetCadRenderManager, TilesetArbRenderManager, TilesetEntitiesRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TilesetGooglePhotosRenderManager, DataSourceStaticKmlManager, GoogleSearchRenderManager, AssemblyRenderManager, RelationsRenderManager, SharedGetters, CesiumParabola, EntityLabel, ViewRenderEngine, TileRenderEngine, TilesetRenderEngine, CESIUM_INSPECTOR_KEY, CESIUM_TIMELINE_KEY, CESIUM_TIMELINE_LIVE_KEY, CESIUM_TIMELINE_LIVE_PADDING_KEY, CESIUM_TIMELINE_INTERVAL_KEY, DEFAULT_LIVE_PADDING_SECONDS, ViewUtils, DrawingUtils, MeasureUtils, EntityUtils, CesiumEntityStyler, CesiumAnimatedProperty, CesiumAnimatedInOut, Draw3dPolygon, Draw3dPolyline, MeasureCreator, Walkthrough, Widget, VIEWER_BOOKMARKS_WIDGET_KEY, WidgetBookmarks, WidgetBranding, WidgetCursorBar, WidgetEmbeddedInfoView, WidgetInfoView, WidgetNavCompass$$1 as WidgetNavCompass, VIEWER_VIEW_BAR_WIDGET_KEY, WidgetViewBar, WidgetControlViewBar, WidgetControlViewBarSearch, VIEWER_LEFT_PANEL_WIDGET_KEY, VIEWER_LEFT_PANEL_CSS_VAR_LEFT, WidgetLeftPanel, WidgetLeftPanelTab, WidgetLeftPanelTabBookmarks };
32340
32901
  //# sourceMappingURL=bruce-cesium.es5.js.map